【问题标题】:SimpleXML: append one tree to anotherSimpleXML:将一棵树附加到另一棵树
【发布时间】:2010-08-05 18:42:17
【问题描述】:

我有两棵 XML 树,想将一棵树作为叶子添加到另一棵树。

显然:

$tree2->addChild('leaf', $tree1);

不起作用,因为它只复制第一个根节点。

好的,所以我想我会遍历整个第一棵树,将每个元素一个接一个地添加到第二棵树。

但是考虑这样的 XML:

<root>
  aaa
  <bbb/>
  ccc
</root>

如何访问“ccc”? tree1-&gt;children() 只返回“bbb”...。

【问题讨论】:

    标签: php simplexml


    【解决方案1】:

    正如您所见,您不能直接使用 SimpleXML 添加“树”。但是,您可以使用一些 DOM 方法为您完成繁重的工作,同时仍然使用相同的底层 XML。

    $xmldict = new SimpleXMLElement('<dictionary><a/><b/><c/></dictionary>');
    $kitty   = new SimpleXMLElement('<cat><sound>meow</sound><texture>fuzzy</texture></cat>');
    
    // Create new DOMElements from the two SimpleXMLElements
    $domdict = dom_import_simplexml($xmldict->c);
    $domcat  = dom_import_simplexml($kitty);
    
    // Import the <cat> into the dictionary document
    $domcat  = $domdict->ownerDocument->importNode($domcat, TRUE);
    
    // Append the <cat> to <c> in the dictionary
    $domdict->appendChild($domcat);
    
    // We can still use SimpleXML! (meow)
    echo $xmldict->c->cat->sound;
    

    【讨论】:

    • 当我这样做时,我正在导入的节点上的命名空间被抛出。我该如何预防?
    【解决方案2】:

    您可以使用这个类来接受子附加的 SimpleXML 对象

    <?php
    
    class MySimpleXMLElement extends SimpleXMLElement
    {
        /**
         * Add SimpleXMLElement code into a SimpleXMLElement
         *
         * @param MySimpleXMLElement $append
         */
        public function appendXML($append)
        {
            if ($append) {
                if (strlen(trim((string)$append)) == 0) {
                    $xml = $this->addChild($append->getName());
                } else {
                    $xml = $this->addChild($append->getName(), (string)$append);
                }
    
                foreach ($append->children() as $child) {
                    $xml->appendXML($child);
                }
    
                foreach ($append->attributes() as $n => $v) {
                    $xml->addAttribute($n, $v);
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      这是来自PHP manual page 评论的不错的解决方案(仅使用 SimpleXML,而不是 DOM):

      function append_simplexml(&$simplexml_to, &$simplexml_from)
      {
          foreach ($simplexml_from->children() as $simplexml_child)
          {
              $simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
              foreach ($simplexml_child->attributes() as $attr_key => $attr_value)
              {
                  $simplexml_temp->addAttribute($attr_key, $attr_value);
              }
      
              append_simplexml($simplexml_temp, $simplexml_child);
          }
      } 
      

      还有使用示例。

      【讨论】:

      • 这很简单。对于我的数据,我需要将 addChild 的第二个参数包装在 htmlspecialchars()
      【解决方案4】:

      非常好的西奥·海康宁 稍作调整以使其按我想要的方式工作

      函数 addsubtree(&$xml1,&$xml2) {// 从两个 SimpleXMLElements 创建新的 DOMElements $dom1 = dom_import_simplexml($xml1); $dom2 = dom_import_simplexml($xml2); // 导入到文档中 $dom2 = $dom1->ownerDocument->importNode($dom2, TRUE); // 附加到 $dom1->appendChild($dom2); } $xml1 = new SimpleXMLElement(''); $xml2 = new SimpleXMLElement(''); $xml2->addChild('test','data'); $temp=$xml1->addChild('sub1'); header('内容类型:文本/xml'); header('Pragma: public'); header('缓存控制:私有'); header('过期:-1'); 添加子树($temp,$xml2); // 我们仍然可以使用 SimpleXML! (喵) 回声 $xml1->asXML();

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-19
        • 2021-01-09
        • 2015-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多