【问题标题】:How to solve a naming conflict when specifying a custom prefix using XPath?使用 XPath 指定自定义前缀时如何解决命名冲突?
【发布时间】:2013-05-21 11:23:46
【问题描述】:

我正在运行 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,那么查询将按预期工作:

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

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

我知道我可以获取文档中使用的前缀和命名空间,但我想要固定的 XPath 查询字符串。

FWIW DOMXPath 也有这个问题(检查过)。

【问题讨论】:

    标签: php xml-parsing


    【解决方案1】:

    除非你真的想研究你选择的任何前缀可能已经在使用的理论上的可能性,否则只需使用一个不可能猜到的前缀。例如前缀:SJDUWISKJDU

    【讨论】:

      猜你喜欢
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 2021-09-11
      相关资源
      最近更新 更多