I have a well working livesearch which takes the results from my XML List. But I need to add many links to it and I wonder if there is a way to automatically sort them alphabetically to save time. I need them sorted from A to Z because the results should not be in a random order.
Is there a way to maybe add them into a php page or something and display them sorted in my XML file? Or maybe work with classes?
<pages>
<link>
<title>Volvo</title>
<url>https://www.example.com</url>
</link>
<link>
<title>Audi</title>
<url>https://www.example.com</url>
</link>
<link>
<title>Mercedes</title>
<url>https://www.example.com</url>
</link>
</pages>
This is the PHP Code:
<?php
$xmlDoc=new DOMDocument();
$xmlDoc->load("links.xml");
$x=$xmlDoc->getElementsByTagName('link');
//get the q parameter from URL
$q=$_GET["q"];
//lookup all links from the xml file if length of q>0
if (strlen($q)>0) {
$hint="";
for($i=0; $i<($x->length); $i++) {
$y=$x->item($i)->getElementsByTagName('title');
$z=$x->item($i)->getElementsByTagName('url');
if ($y->item(0)->nodeType==1) {
//find a link matching the search text
if (strpos(strtolower($y->item(0)->childNodes->item(0)->nodeValue), strtolower($q)) === 0) {
if ($hint=="") {
$hint="<a href='" .
$z->item(0)->childNodes->item(0)->nodeValue .
"' target='_blank'>" .
$y->item(0)->childNodes->item(0)->nodeValue . "</a>";
} else {
$hint=$hint . "<br /><a href='" .
$z->item(0)->childNodes->item(0)->nodeValue .
"' target='_blank'>" .
$y->item(0)->childNodes->item(0)->nodeValue . "</a>";
}
}
}
}
}
// Set output to "no suggestion" if no hint was found
// or to the correct values
if ($hint=="") {
$response="no suggestion";
} else {
$response=$hint;
}
//output the response
echo $response;
?>
The DOM methods return node lists, more specific a \\DOMNodeList object. This object implements the Traversable
interface (The parent interface for Iterators). You can use iterator_to_array()
to convert the node list into an array and usort()
to sort that array.
To filter the link nodes directly you can use an Xpath expression that calls back into PHP.
// bootstrap the link xml
$source = new DOMDocument();
$source->loadXml(getXML());
$xpath = new DOMXpath($source);
// use ext/intl transliterator to create a lowercase ascii string
function normalize(string $string) {
return \Transliterator::create('Any-Lower; Latin-ASCII')->transliterate($string);
}
// register the "normalize" function
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPhpFunctions(['normalize']);
// build an expression that filters the nodes using a search string
$searchFor = 'd';
$expression = '//link[
contains(php:function("normalize", string(title)), "'.$searchFor.'")
]';
// map data into a nested array
$links = array_map(
function(\DOMNode $node) use ($xpath) {
return [
'title' => $xpath->evaluate('string(title)', $node),
'url' => $xpath->evaluate('string(url)', $node)
];
},
iterator_to_array($xpath->evaluate($expression))
);
// create a locale specific string collator
$collator = new Collator('en_US');
// sort the link data array
usort(
$links,
function(array $a, array $b) use ($collator) {
return $collator->compare($a['title'], $b['title']);
}
);
var_dump($links);
Output:
array(2) {
[0]=>
array(2) {
["title"]=>
string(4) "Audi"
["url"]=>
string(23) "https://www.example.com"
}
[1]=>
array(2) {
["title"]=>
string(8) "Mercedes"
["url"]=>
string(23) "https://www.example.com"
}
}
DOM can be used to create the HTML output also. This allows the DOM serializer to take care of special characters.
// a target document for the HTML output
$target = new DOMDocument();
// fragments are node lists that can be treated as a single node
$targetFragment = $target->createDocumentFragment();
foreach($links as $link) {
// if the fragment contains nodes add a break
if ($targetFragment->hasChildNodes()) {
$targetFragment->appendChild($target->createElement('br'));
}
// create and append "a" element node
$targetFragment->appendChild(
$a = $target->createElement('a')
);
$a->setAttribute('target', '_blank');
$a->setAttribute('href', $link['url']);
$a->textContent = $link['title'];
}
// save the fragment as HTML
echo $target->saveHTML($targetFragment);
Output:
<a target="_blank" href="https://www.example.com">Audi</a><br><a target="_blank" href="https://www.example.com">Mercedes</a>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.