Domdocument und DomxPath sind zwei sehr leistungsstarke Tools, wenn sie PHP verwenden, um XML -Daten zu verarbeiten. Insbesondere wenn komplexe XML -Abfragen erforderlich sind, kann die Verwendung von Namespaces und XPath -Ausdrücken die Flexibilität und Genauigkeit erheblich verbessern. In diesem Artikel wird vorgestellt, wie Sie die RegisterXPathNameSpace -Methode und die benutzerdefinierte XPath -Funktion kombinieren, um Ihre XML -Abfragefunktionen zu erweitern und zu verbessern.
In vielen XML -Dokumenten haben Elemente und Attribute in der Regel Präfixe für Namespace. Zum Beispiel:
<span><span><span class="hljs-tag"><<span class="hljs-name">root</span></span></span><span> </span><span><span class="hljs-attr">xmlns:h</span></span><span>=</span><span><span class="hljs-string">"http://www.w3.org/TR/html4/"</span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:table</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:tr</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:td</span></span></span><span>>Apples</span><span><span class="hljs-tag"></<span class="hljs-name">h:td</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:td</span></span></span><span>>Bananas</span><span><span class="hljs-tag"></<span class="hljs-name">h:td</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">h:tr</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">h:table</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">root</span></span></span><span>>
</span></span>
Um Knoten wie <H: TD> korrekt abfragen, muss der XPath -Ausdruck den Namespace -URI kennen, der dem Präfix h entspricht. In diesem Fall ist RegisterXPathNameSpace nützlich.
<span><span><span class="hljs-variable">$xml</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">DOMDocument</span></span><span>();
</span><span><span class="hljs-variable">$xml</span></span><span>-></span><span><span class="hljs-title function_ invoke__">loadXML</span></span><span>(</span><span><span class="hljs-variable">$yourXmlString</span></span><span>);
</span><span><span class="hljs-variable">$xpath</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">DOMXPath</span></span><span>(</span><span><span class="hljs-variable">$xml</span></span><span>);
</span><span><span class="hljs-variable">$xpath</span></span><span>-></span><span><span class="hljs-title function_ invoke__">registerNamespace</span></span><span>(</span><span><span class="hljs-string">"h"</span></span><span>, </span><span><span class="hljs-string">"http://www.w3.org/TR/html4/"</span></span><span>);
</span><span><span class="hljs-variable">$tds</span></span><span> = </span><span><span class="hljs-variable">$xpath</span></span><span>-></span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"//h:td"</span></span><span>);
</span></span>
Obwohl die XPath-Sprache selbst leistungsstark ist, erfüllen in einigen Geschäftslogikszenarien die integrierten XPath-Funktionen möglicherweise nicht den Anforderungen. Zum Beispiel möchten wir eine Funktion verwenden, um festzustellen, ob der Wert eines Elements in einer Datenbank oder einem Array erscheint, oder um eine komplexere String -Verarbeitung durchzuführen.
PHP unterstützt nativ nicht die Injektion von benutzerdefinierten Funktionen in XPath, kann jedoch teilweise durch Problemumgehungen simuliert werden, z .
Es ist jedoch häufiger, den Namespace zu registrieren und die XML vor der Verwendung von XPath -Abfrage vorzuarbeiten und dann den Knoten mit benutzerdefinierten Funktionen zu bedienen.
Angenommen, Sie haben das folgende XML -Dokument mit mehreren <element> Knoten mit Namespaces:
<span><span><span class="hljs-tag"><<span class="hljs-name">catalog</span></span></span><span> </span><span><span class="hljs-attr">xmlns:bk</span></span><span>=</span><span><span class="hljs-string">"http://example.com/book"</span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">bk:item</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">bk:title</span></span></span><span>>PHP Programmierung</span><span><span class="hljs-tag"></<span class="hljs-name">bk:title</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">bk:price</span></span></span><span>>45</span><span><span class="hljs-tag"></<span class="hljs-name">bk:price</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">bk:item</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">bk:item</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">bk:title</span></span></span><span>>Java Programmierung</span><span><span class="hljs-tag"></<span class="hljs-name">bk:title</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">bk:price</span></span></span><span>>55</span><span><span class="hljs-tag"></<span class="hljs-name">bk:price</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">bk:item</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">catalog</span></span></span><span>>
</span></span>
Sie möchten alle Buchtitel zum Preis von weniger als 50 Yuan abfragen. XPath selbst unterstützt numerische Vergleiche:
<span><span><span class="hljs-variable">$xpath</span></span><span>-></span><span><span class="hljs-title function_ invoke__">registerNamespace</span></span><span>(</span><span><span class="hljs-string">"bk"</span></span><span>, </span><span><span class="hljs-string">"http://example.com/book"</span></span><span>);
</span><span><span class="hljs-variable">$nodes</span></span><span> = </span><span><span class="hljs-variable">$xpath</span></span><span>-></span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"//bk:item[bk:price < 50]/bk:title"</span></span><span>);
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$nodes</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$node</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$node</span></span><span>->nodeValue . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span></span>
Wenn Sie eine komplexere Logik implementieren möchten (z. B. einen Preis unter 50 und den Titel "PHP"), können Sie mehrere XPath -Bedingungen kombinieren:
<span><span><span class="hljs-variable">$nodes</span></span><span> = </span><span><span class="hljs-variable">$xpath</span></span><span>-></span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"//bk:item[bk:price < 50 and contains(bk:title, 'PHP')]/bk:title"</span></span><span>);
</span></span>
Wenn die Logik jedoch komplizierter ist, z. B. "Nur Knoten mit dem Titel, der ein Wort in der Schlüsselworttabelle enthält", müssen Sie die Ergebnisse mit einer benutzerdefinierten Funktion nach der Abfrage filtern:
<span><span><span class="hljs-variable">$keywords</span></span><span> = [</span><span><span class="hljs-string">'PHP'</span></span><span>, </span><span><span class="hljs-string">'MySQL'</span></span><span>, </span><span><span class="hljs-string">'Laravel'</span></span><span>];
</span><span><span class="hljs-variable">$nodes</span></span><span> = </span><span><span class="hljs-variable">$xpath</span></span><span>-></span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"//bk:item/bk:title"</span></span><span>);
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$nodes</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$node</span></span><span>) {
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$keywords</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$word</span></span><span>) {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">stripos</span></span><span>(</span><span><span class="hljs-variable">$node</span></span><span>->nodeValue, </span><span><span class="hljs-variable">$word</span></span><span>) !== </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$node</span></span><span>->nodeValue . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span><span><span class="hljs-keyword">break</span></span><span>;
}
}
}
</span></span>
Obwohl dies eine logische Verarbeitung außerhalb des XPath -Queryergebnisses ist, kombiniert sie im Wesentlichen XPath -Abfragefunktionen und PHP -benutzerdefinierte Logik.
Wenn Sie PHP -Funktionen tatsächlich in die XPath -Logik einbetten müssen, sollten Sie XSLTProcessor- und PHP -Erweiterungsfunktionen kombinieren. Beispielsweise wird das logische Urteilsvermögen durch Registrierung von Erweiterungsfunktionen (z. B. PHP: Funktionsstring ('your_function') ) implementiert - dies ist eine Verwendung höherer Ordnung und erfordert die Möglichkeit, die XSL -Erweiterung in PHP zu ermöglichen und auf die Sicherheit zu achten.