현재 위치: > 최신 기사 목록> RegisterXPathNamespace를 사용자 정의 xpath 함수와 결합하여 XML 쿼리 기능을 확장하는 방법은 무엇입니까?

RegisterXPathNamespace를 사용자 정의 xpath 함수와 결합하여 XML 쿼리 기능을 확장하는 방법은 무엇입니까?

M66 2025-07-08

DomDocumentDomxPath는 PHP를 사용하여 XML 데이터를 처리 할 때 매우 강력한 두 가지 도구입니다. 특히 복잡한 XML 쿼리가 필요한 경우 네임 스페이스와 XPath 표현식을 사용하면 유연성과 정확성을 크게 향상시킬 수 있습니다. 이 기사에서는 registerxpathnamespace 메소드와 사용자 정의 XPath 함수를 결합하여 XML 쿼리 기능을 확장하고 향상시키는 방법을 소개합니다.

1. XPath에서 네임 스페이스의 중요성을 이해하십시오

많은 XML 문서에서 요소와 속성에는 일반적으로 네임 스페이스 접두사가 있습니다. 예를 들어:

 <span><span><span class="hljs-tag">&lt;<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>&gt;
  </span><span><span class="hljs-tag">&lt;<span class="hljs-name">h:table</span></span></span><span>&gt;
    </span><span><span class="hljs-tag">&lt;<span class="hljs-name">h:tr</span></span></span><span>&gt;
      </span><span><span class="hljs-tag">&lt;<span class="hljs-name">h:td</span></span></span><span>&gt;Apples</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">h:td</span></span></span><span>&gt;
      </span><span><span class="hljs-tag">&lt;<span class="hljs-name">h:td</span></span></span><span>&gt;Bananas</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">h:td</span></span></span><span>&gt;
    </span><span><span class="hljs-tag">&lt;/<span class="hljs-name">h:tr</span></span></span><span>&gt;
  </span><span><span class="hljs-tag">&lt;/<span class="hljs-name">h:table</span></span></span><span>&gt;
</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">root</span></span></span><span>&gt;
</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>-&gt;</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>-&gt;</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>-&gt;</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>

2. XPath 함수를 사용자 정의하기위한 동기

XPath 언어 자체는 강력하지만 일부 비즈니스 로직 시나리오에서는 내장 XPATH 기능이 요구를 충족시키지 못할 수 있습니다. 예를 들어, 기능을 사용하여 요소 값이 데이터베이스 또는 배열에 나타나는지 여부를 결정하거나보다 복잡한 문자열 처리를 수행 할 수 있습니다.

PHP는 기본적으로 사용자 정의 기능을 XPath에 주입하는 것을 지원하지 않지만 쿼리 결과를 통과 할 때 LIBXMLXSLTProcessor를 결합 할 때 PHP 기능을 호출하여 논리를 구현하는 것과 같은 해결 방법으로 부분적으로 시뮬레이션 할 수 있습니다.

그러나 XPath 쿼리를 사용하기 전에 네임 스페이스를 등록하고 XML을 전제로 처리 한 다음 사용자 정의 함수로 노드를 작동하는 것이 더 일반적입니다.

3. 네임 스페이스와 사용자 정의 로직을 결합한 실제 사례

네임 스페이스가있는 여러 <item> 노드가 포함 된 다음 XML 문서가 있다고 가정합니다.

 <span><span><span class="hljs-tag">&lt;<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>&gt;
  </span><span><span class="hljs-tag">&lt;<span class="hljs-name">bk:item</span></span></span><span>&gt;
    </span><span><span class="hljs-tag">&lt;<span class="hljs-name">bk:title</span></span></span><span>&gt;PHP 프로그램 작성</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">bk:title</span></span></span><span>&gt;
    </span><span><span class="hljs-tag">&lt;<span class="hljs-name">bk:price</span></span></span><span>&gt;45</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">bk:price</span></span></span><span>&gt;
  </span><span><span class="hljs-tag">&lt;/<span class="hljs-name">bk:item</span></span></span><span>&gt;
  </span><span><span class="hljs-tag">&lt;<span class="hljs-name">bk:item</span></span></span><span>&gt;
    </span><span><span class="hljs-tag">&lt;<span class="hljs-name">bk:title</span></span></span><span>&gt;Java 프로그램 작성</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">bk:title</span></span></span><span>&gt;
    </span><span><span class="hljs-tag">&lt;<span class="hljs-name">bk:price</span></span></span><span>&gt;55</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">bk:price</span></span></span><span>&gt;
  </span><span><span class="hljs-tag">&lt;/<span class="hljs-name">bk:item</span></span></span><span>&gt;
</span><span><span class="hljs-tag">&lt;/<span class="hljs-name">catalog</span></span></span><span>&gt;
</span></span>

50 위안 미만의 가격으로 모든 책 제목을 쿼리하려고합니다. XPath 자체는 수치 비교를 지원합니다.

 <span><span><span class="hljs-variable">$xpath</span></span><span>-&gt;</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>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"//bk:item[bk:price &lt; 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>-&gt;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>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"//bk:item[bk:price &lt; 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>-&gt;</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>-&gt;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>-&gt;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 사용자 정의 로직을 결합합니다.

4. 확장 된 판독 : XSLT (고급)와 함께 사용자 정의 기능 사용

실제로 PHP 기능을 XPATH 로직에 포함시켜야하는 경우 XSLTProcessor 및 PHP 확장 기능을 결합하는 것을 고려하십시오. 예를 들어, 논리적 판단은 확장 함수를 등록하여 구현됩니다 (예 : PHP : FUNCTIONSTRING ( 'Your_Function') ) - 이는 더 높은 차이 사용량이며 PHP에서 XSL 확장을 가능하게하고 보안에주의를 기울여야합니다.