Reputation: 45
First, i know that there are already some questions aubout similar things (Searching an XML file using PHP Load external xml file?), but i CAN'T make ANY PHP, so the following (search.php) is what I copy-pasted in PHP:
<html>
<head>
<title>Search</title>
</head>
<body>
<?php
$search = $_POST["search"];
$xml=simplexml_load_file("inhaltsverzeichniss.xml") or die("Error: Cannot create object");
$result = $xml->xpath('//array/entry/tags[.="$search"]');
while(list( , $node) = each($result)) {
echo '/array/entry/tags: ',$node,"\n";
}
?>
</body>
Then this is my HTML code (in case someone needs it):
<form action="search.php" method="post" >
<input type="text" name="search" placeholder="search for stuff" >
<input type="submit" name="search_button" value="Suche" >
</form>
and this is the XML Document I want to search in (inhaltsverzichniss.xml):
<?xml version="1.0" encoding="UTF-8"?>
<array>
<entry>
<url>Zeitformen Spanisch.odp</url>
<name>Zeitformen Tabelle</name>
<tags>spanisch</tags>
</entry>
<entry>
<url>german-stuff.odt</url>
<name>etwas Deutsches</name>
<tags>german</tags>
</entry>
<entry>
<url>something_english.html</url>
<name>english things</name>
<tags>english</tags>
</entry>
<entry>
<url>other-data.fileextension</url>
<name>cool name</name>
<tags>etc.</tags>
</entry>
</array>
What I want to do is search for tags written in the search form, and give the whole corresponding entry out. (like following:<a href"$url">$name</a><br>Tags: $tags
)
EDIT: this is my current XML with entries with multiple tags (changed it to "tag"):
<array>
<entry>
<url>spanisch/Zeitformen_Spanisch.ods</url>
<name>Zeitformen Tabelle</name>
<tag>spanisch</tag>
</entry>
<entry>
<url>german-stuff.odt</url>
<name>etwas Deutsches</name>
<tag>deutsch</tag>
<tag>spanisch</tag>
<tag>englisch</tag>
</entry>
<entry>
<url>something_english.html</url>
<name>english things</name>
<tag>spanisch</tag>
<tag>englisch</tag>
</entry>
<entry>
<url>other-data.fileextension</url>
<name>cool name</name>
<tag>etc.</tag>
</entry>
</array>
Upvotes: 2
Views: 1181
Reputation: 317119
Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.
You are using single quotes in
$result = $xml->xpath('//array/entry/tags[.="$search"]');
but single quotes will treat the string content as literal strings. It won't interpolate $search
like you think it does.
Change your code to
$result = $xml->xpath("//array/entry/tags[.='$search']");
and it will use the value of $search
instead of the literal string "$search"
.
However, since you want to print the full entry element, it would be better to use this XPath
$result = $xml->xpath("/array/entry[tags='$search']");
For readability I prefer
$result = $xml->xpath(sprintf('/array/entry[tags="%s"]', $search));
This will give you all the <entry>
elements, instead of the <tags>
elements in the $result
. And while //array
with a double slash does work, it's unneeded and performs somewhat worse than the direct path. That's because it will try to find the nodes regardless of position in the document.
You can then print it like you asked for like this:
foreach ($result as $entry) {
printf(
'<a href="%s">%s</a><br>Tags: %s%s',
urlencode($entry->url),
htmlspecialchars($entry->name),
htmlspecialchars($entry->tags),
PHP_EOL
);
}
Regarding your edit with multiple tag elements:
The XPath above will already find the correct entries. To display all tags, you can change the line
htmlspecialchars($entry->tags),
to (don't forget to adjust the xpath to read tag instead of tags):
implode_tags($entry->tag),
with the implode_tags function being defined as
function implode_tags(\SimpleXMLElement $tags) {
$allTags = [];
foreach ($tags as $tag) {
$allTags[] = htmlspecialchars($tag);
}
return implode(", ", $allTags);
}
This should then return something like "deutsch, spanisch, englisch"
See full demo at https://eval.in/885485
Upvotes: 1