DomDocument 와 DomxPath는 PHP를 사용하여 XML 데이터를 처리 할 때 매우 강력한 두 가지 도구입니다. 특히 복잡한 XML 쿼리가 필요한 경우 네임 스페이스와 XPath 표현식을 사용하면 유연성과 정확성을 크게 향상시킬 수 있습니다. 이 기사에서는 registerxpathnamespace 메소드와 사용자 정의 XPath 함수를 결합하여 XML 쿼리 기능을 확장하고 향상시키는 방법을 소개합니다.
많은 XML 문서에서 요소와 속성에는 일반적으로 네임 스페이스 접두사가 있습니다. 예를 들어:
<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>
<h : td> 와 같은 노드를 올바르게 쿼리하려면 XPath 표현식은 접두사 H 에 해당하는 네임 스페이스 URI를 알아야합니다. registerxpathnamespace가 편리 할 때입니다.
<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>
XPath 언어 자체는 강력하지만 일부 비즈니스 로직 시나리오에서는 내장 XPATH 기능이 요구를 충족시키지 못할 수 있습니다. 예를 들어, 기능을 사용하여 요소 값이 데이터베이스 또는 배열에 나타나는지 여부를 결정하거나보다 복잡한 문자열 처리를 수행 할 수 있습니다.
PHP는 기본적으로 사용자 정의 기능을 XPath에 주입하는 것을 지원하지 않지만 쿼리 결과를 통과 할 때 LIBXML 및 XSLTProcessor를 결합 할 때 PHP 기능을 호출하여 논리를 구현하는 것과 같은 해결 방법으로 부분적으로 시뮬레이션 할 수 있습니다.
그러나 XPath 쿼리를 사용하기 전에 네임 스페이스를 등록하고 XML을 전제로 처리 한 다음 사용자 정의 함수로 노드를 작동하는 것이 더 일반적입니다.
네임 스페이스가있는 여러 <item> 노드가 포함 된 다음 XML 문서가 있다고 가정합니다.
<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 프로그램 작성</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 프로그램 작성</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>
50 위안 미만의 가격으로 모든 책 제목을 쿼리하려고합니다. XPath 자체는 수치 비교를 지원합니다.
<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>
더 복잡한 논리 (예 : 50 미만의 가격 및 제목에 "PHP"가 포함되어 있음)를 구현하려면 여러 XPATH 조건을 결합 할 수 있습니다.
<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>
그러나 논리가 "키워드 테이블에 단어가 포함 된 제목으로 노드를 유지하는 것만 보관하는 것"과 같이 더 복잡한 경우 쿼리 후 사용자 정의 기능으로 결과를 필터링해야합니다.
<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>
이것은 XPath 쿼리 결과 외부의 논리적 처리이지만 본질적으로 XPath 쿼리 기능과 PHP 사용자 정의 로직을 결합합니다.
실제로 PHP 기능을 XPATH 로직에 포함시켜야하는 경우 XSLTProcessor 및 PHP 확장 기능을 결합하는 것을 고려하십시오. 예를 들어, 논리적 판단은 확장 함수를 등록하여 구현됩니다 (예 : PHP : FUNCTIONSTRING ( 'Your_Function') ) - 이는 더 높은 차이 사용량이며 PHP에서 XSL 확장을 가능하게하고 보안에주의를 기울여야합니다.