使用XPath指定自定义前缀时如何解决命名冲突?

时间:2013-05-21 11:23:46

标签: php xml-parsing

我正在运行PHP 5.4.14,我正在尝试使用XPath在XML文档中进行搜索。我不知道每个名称空间将使用哪个名称空间前缀,因此我使用registerXPathNamespace()定义自己的前缀。

问题是如果我为XPath注册一个新的前缀(例如C)并且文档已经在使用它,那么XPath查询将不使用我的前缀而是使用原始前缀。

让我向您展示一个显示此行为的示例代码:

<?php
$body = <<<EOF                                                              
<multistatus xmlns="DAV:" xmlns:VC="urn:ietf:params:xml:ns:carddav" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:C1="http://calendarserver.org/ns/">
 <response>                                                                 
  <href>/caldav.php/jorge/contacts/</href>                                  
  <propstat>                                                                
   <prop>                                                                   
    <current-user-principal>                                                
     <href>/caldav.php/jorge/</href>                                        
    </current-user-principal>                                               
    <resourcetype>                                                          
     <collection/>                                                          
     <VC:addressbook/>                                                      
    </resourcetype>                                                         
    <displayname/>                                                          
    <VC:addressbook-home-set>                                               
     <href>/caldav.php/jorge/</href>                                        
    </VC:addressbook-home-set>                                              
   </prop>                                                                  
   <status>HTTP/1.1 200 OK</status>                                         
  </propstat>                                                               
 </response>                                                                
</multistatus>                                                              
EOF;                                                                        

$xml = new SimpleXMLElement($body);                                         

$xml->registerXPathNamespace('C', 'urn:ietf:params:xml:ns:carddav');        
$xpresult = $xml->xpath('//C:addressbook-home-set');                        

var_dump($xpresult);                                                        

如果你运行它,你会看到查询没有返回任何结果。

令人惊讶的是,如果我将已注册的前缀从 C 更改为任何其他尚未定义的前缀(例如 X ),则查询将按预期工作:< / p>

$xml->registerXPathNamespace('X', 'urn:ietf:params:xml:ns:carddav');        
$xpresult = $xml->xpath('//X:addressbook-home-set');    

我做错了吗?鉴于我不知道将提前使用哪些前缀,是否可以设置自定义前缀并确保它不会与文档中的其他前缀冲突,除了使用丑陋的 MYPROGRAMUNUSEDPREFIXC 前缀?

我知道我可以获得文档中使用的前缀和名称空间,但我想要修复XPath查询字符串。

FWIW DOMXPath也有这个问题(选中它)。

1 个答案:

答案 0 :(得分:0)

除非你真的想进入你选择的任何前缀可能已经被使用的理论可能性,否则只需使用一个不太可能的猜测。例如前缀:SJDUWISKJDU