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 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘