【问题标题】:Parse tags with colons using SimpleXML xpath in PHP [duplicate]在 PHP 中使用 SimpleXML xpath 解析带有冒号的标签 [重复]
【发布时间】:2013-03-25 16:25:22
【问题描述】:

有没有一种简单的方法可以使用 SimpleXML xpath 来解析标签名称中包含冒号的标签?

示例:

<v12:ProcessShipmentResponse>SUCCESS</v12:ProcessShipmentResponse>

这是我用来解析没有命名空间但与命名空间标签中断的标签的代码。

    $xml = simplexml_load_string($responseXMLL, NULL, NULL, 'http://schemas.xmlsoap.org/soap/envelope/');


    foreach ($xml->xpath('soapenv:Body') as $body) {


        $custInfoArr['status'] = (string) $body->v12:ProcessShipmentReply->v12:HighestSeverity;
        $custInfoArr['trackingCode'] = (string) $body->v12:ProcessShipmentReply->v12:CompletedShipmentDetail->v12:CompletedPackageDetails->v12:TrackingIds->v12:TrackingNumber;
        $custInfoArr['labelCode'] = (string) $body->v12:ProcessShipmentReply->v12:CompletedShipmentDetail->v12:CompletedPackageDetails->v12:Label->v12:Parts->v12:Image;

    }

【问题讨论】:

    标签: php xpath simplexml xml-namespaces


    【解决方案1】:

    看看this

     public bool SimpleXMLElement::registerXPathNamespace(string $prefix,string $ns);
    

    来自php手册:

    为下一个 XPath 查询创建一个前缀/ns 上下文。尤其, 如果给定 XML 文档的提供者更改了 命名空间前缀。 registerXPathNamespace 将为 关联的命名空间,允许访问该命名空间中的节点 命名空间,无需更改代码以允许新的 提供者指定的前缀。

    【讨论】:

    • 这仅与使用 XPath 有关,与 SimpleXML 提供的普通对象和数组样式访问无关(-&gt;node['attribute'])。
    • 是的,但是您并没有真正解释如何使用它,这看起来像是如何修复 OP 的代码,除了一行之外 not 使用XPath,并且不需要。
    • @DonCallisto:您不需要在 SimpleXML 中注册已经注册的前缀。此外,最好建议直接选择 ProcessShipmentReply 元素,因此前缀在 foreach 中不碍事。这真的不是一个有用的答案,所以也许这就是 DV 出现的原因。特别是(我必须承认)这是一个骗子的骗子。
    【解决方案2】:

    这已经被问过很多次了。这些不是“带冒号的标签”,它们是 XML 命名空间,需要在任何解析器中进行特殊处理。

    对于 SimpleXML,这是由 -&gt;children()-&gt;attributes() 方法提供的。

    您可以依赖别名/前缀不变(不能保证这一点,因为 XML 文档的“语义”不会改变)并使用 true 作为第二个参数(在您的情况下为 @987654326 @) 或为命名空间 URI 设置一个常量(保证不会更改)并传递它(在您的情况下为 define('XMLNS_FEDEX_V12', 'http://fedex.com/ws/ship/v12'); /* ... */ $body-&gt;children(XMLNS_FEDEX_V12))。

    【讨论】:

      【解决方案3】:

      需要像这样注册命名空间。这是一个工作示例,以防有人需要。

              $xml = simplexml_load_string($result, NULL, NULL, 'http://schemas.xmlsoap.org/soap/envelope/');
              $xml->registerXPathNamespace('env', 'http://schemas.xmlsoap.org/soap/envelope/');
              $xml->registerXPathNamespace('v12', 'http://fedex.com/ws/ship/v12');
              $bodies = $xml->xpath('env:Body');
      
              foreach($bodies as $body){
      
                $reply = $body->children('v12', TRUE)->ProcessShipmentReply;
                $custInfoArr['status'] = (string) $reply->HighestSeverity;
                $custInfoArr['trackingCode'] = (string) $reply->CompletedShipmentDetail->CompletedPackageDetails->TrackingIds->TrackingNumber;
                $custInfoArr['labelCode'] = (string) $reply->CompletedShipmentDetail->CompletedPackageDetails->Label->Parts->Image;
      
      
              }
      

      【讨论】:

      • registerXPathNamespace 仅在您使用 -&gt;xpath() 时才是必需的。 -&gt;children() 方法完全基于 XML 本身。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多