/ / php xpath-Abfrage zum Abrufen des übergeordneten Knotens basierend auf dem Wert beim Wiederholen der untergeordneten Knoten - php, xml, xpath

php xpath-Abfrage, um den übergeordneten Knoten basierend auf dem Wert in sich wiederholenden untergeordneten Knoten zu erhalten - php, xml, xpath

Ich habe eine XML-Datei wie folgt aufgebaut:

<pictures>
<picture>
<title></title>
<description></description>
<facts>
<date></date>
<place>Unites States</place>
</facts>
<people>
<person>John</person>
<person>Sue</person>
</people>
</picture>
<picture>
<title></title>
<description></description>
<facts>
<date></date>
<place>Canada</place>
</facts>
<people>
<person>Sue</person>
<person>Jane</person>
</people>
</picture>
<picture>
<title></title>
<description></description>
<facts>
<date></date>
<place>Canada</place>
</facts>
<people>
<person>John</person>
<person>Joe</person>
<person>Harry</person>
</people>
</picture>
<pictures>

In einem Fall muss ich nach Bildern suchen, bei denen place = "Canada" ist. Ich habe einen XPath, der dies in Ordnung bringt:

$place = "Canada";
$pics = ($pictures->xpath("//*[place="$place"]"));

Dadurch wird der gesamte "Bild" -Knoten gezogen, sodass Titel, Beschreibung usw. angezeigt werden können. Ich muss noch alle Bilder finden, bei denen person = $ person ist. Ich verwende die gleiche Art Abfrage wie oben:

$person = "John";
$pics = ($pictures->xpath("//*[person="$person"]"));

In diesem Fall kennt die Abfrage offenbar dortsind 2 Bilder mit John, aber ich erhalte keinen der Werte für die anderen Knoten. Ich vermute, es hat etwas mit dem wiederholten untergeordneten Knoten zu tun, kann aber nicht herausfinden, wie der XPath umstrukturiert werden kann, um alle zu ziehen Ich habe versucht, Attribute anstelle von Werten zu verwenden (und habe die Abfrage entsprechend geändert), habe aber das gleiche Ergebnis erzielt. Kann mir jemand raten, was ich hier vermisse?

Antworten:

3 für die Antwort № 1

Ersetzen wir zuerst die Variablen. Dadurch wird PHP aus dem Bild gerissen. Das Problem ist nur der richtige XPath-Ausdruck.

//*[place="Canada"]

stimmt mit jedem Elementknoten überein, der einen untergeordneten Elementknoten hat place mit dem Textinhalt Canada.

Dies ist das facts Elementknoten - nicht der picture.

Das Abrufen des Bilder-Knotens ist etwas anders:

//picture[facts/place="Canada"]

Dies würde JEDEN Bildknoten bei JEDER TIEFE auswählen, der der Bedingung entspricht.

picture[facts/place="Canada"]

Gibt dasselbe Ergebnis mit dem bereitgestellten XML zurück, ist jedoch spezifischer und stimmt nur überein picture Elementknoten, die untergeordnete Elemente des Dokumentelements sind.

Jetzt validieren die people Knoten ist in etwa gleich:

picture[people/person="John"]

Sie können sogar die beiden Bedingungen kombinieren:

picture[facts/place="Canada" and people/person="John"]

Hier ist eine kleine Demo:

$element = new SimpleXMLElement($xml);

$expressions = [
"//*[place="Canada"]",
"//picture[facts/place="Canada"]",
"picture[facts/place="Canada"]",
"picture[people/person="John"]",
"picture[facts/place="Canada" and people/person="John"]",
];

foreach ($expressions as $expression) {
echo $expression, "n", str_repeat("-", 60), "n";
foreach ($element->xpath($expression) as $index => $found) {
echo "#", $index, "n", $found->asXml(), "n";
}
echo "n";
}

TIPP: Sie verwenden dyamic-Werte in Ihren XPath-Ausdrücken. Zeichenfolgenliterale in XPath 1.0 unterstützen kein Escape. Ein Anführungszeichen in der Variablen kann Ihren Ausdruck unterbrechen. Sehen diese Antwort.