使用PHP中的SimpleXML xpath使用冒号分析标记

时间:2013-03-25 16:25:23

标签: php xpath simplexml xml-namespaces

是否有一种简单的方法可以使用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;

    }

3 个答案:

答案 0 :(得分:0)

看看this

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

来自php手册:

  

为下一个XPath查询创建前缀/ ns上下文。特别是,   如果给定XML文档的提供者改变了,那么这很有用   名称空间前缀。 registerXPathNamespace将为其创建前缀   关联的命名空间,允许一个人访问其中的节点   名称空间,无需更改代码以允许新的   前提是由提供商决定的。

答案 1 :(得分:0)

以前曾多次询问过这个问题。这些不是“冒号标签”,它们是XML命名空间,需要在任何解析器中进行特殊处理。

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

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

答案 2 :(得分:-1)

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

        $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;


        }