dongsui4658 2015-03-27 11:06
浏览 55
已采纳

如何获取标签“外部”的XML内容(使用PHP的SimpleXMLElement)?

The XML:

<order>
    XXX
    <orderValue>YYY</orderValue>
</order>

The Problem:

I cannot figure out how to get the pure XXX (with PHP's SimpleXMLElement) as it's not reachable via a direct tag. $order->orderValue will deliver YYY for sure, $order will deliver everything inside the order-tag. The XML is valid according to codebeautify.org-validator and xmlwf-shell-validator.

  • 写回答

2条回答 默认 最新

  • drip5880 2015-03-27 18:59
    关注

    The XML you have:

    <order>
        XXX
        <orderValue>YYY</orderValue>
    </order>
    

    is technically speaking not compatible with Simplexml in PHP. Even though Clément Malet outlined that this tiny fragment did work in the isolated example he presents in his answer, you're referring to the more general problem here that Simplexml is incompatible for data-access for more differentiated (and possible) arrangement of document nodes.

    Don't get me wrong, the XML is valid and Simplexml will load it (it won't destroy the document neither). But the interface of SimpleXMLElement can't address the mixed child-nodes you have here to the level of detail you likely need in your case:

    1. a text-node "XXX"
    2. an element-node <orderValue>

    Simplexml simplifies the access to data in the XML document by technically allowing a parent element to only have one type of child-nodes. So only elements or text(s).

    For everything more differentiated there is the sister-library named Dom which works interchangeably. And by extending SimpleXMLElement you can even create some extension to your existing code here without changing too much of it.

    Let's add a new method to SimpleXMLElement that returns all child-nodes of any element you're interested in (text-nodes and element-nodes) and name that method childNodes:

    /**
     * Extend SimpleXMLElement to access child-nodes more differentiated.
     *
     * Demonstration to work together with DOM sister library
     */
    class MyXml extends SimpleXMLElement
    {
        public function childNodes() {
            $nodes = [];
            foreach(dom_import_simplexml($this)->childNodes as $node) {
                if ($node instanceof DOMText) {
                    $nodes[] = $node->nodeValue;
                } elseif ($node instanceof DOMElement) {
                    $nodes[] = simplexml_import_dom($node);
                } // ... other node-types ignored in this example
            }
            return $nodes;
        }
    }
    

    Depending on how you create your SimpleXMLElement you can pass some parameter telling which SimpleXMLElement class to use. Here my example with a string:

    $buffer = <<<XML
    <doc>
      <order>
          XXX <!-- XXX is never reachable as-is with pure SimpleXML -->
          <orderValue>YYY</orderValue>
          ZZZ <!-- same for ZZZ -->
      </order>
    </doc>
    XML;
    
    $xml = simplexml_load_string($buffer, 'MyXml');
    

    I create the SimpleXMLElement with the simplexml_load_string function. It has a second parameter where I can pass the classname to be used. This allows you then to use the added method:

    var_dump($xml->order->childNodes()[0]); // first child-node string(11) "
          XXX "
    

    As you can see, you perhaps can't do it with "pure" Simplexml but you can extend the interface and benefit from the much more detailed access the DOM sister-library offers.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加
  • ¥15 用ns3仿真出5G核心网网元
  • ¥15 matlab答疑 关于海上风电的爬坡事件检测