【问题标题】:PHP DOMDocument: how to incorporate a string of xml?PHP DOMDocument:如何合并一串xml?
【发布时间】:2015-02-05 15:45:58
【问题描述】:

我正在构建一个 xml 文件,并且需要包含保存在数据库中的一段 xml(是的,我希望不是这样)。

    // parent element
    $parent = $dom->createElement('RecipeIngredients');

    // the xml string I want to include
    $xmlStr = $row['ingredientSectionXml'];

    // load xml string into domDocument
    $dom->loadXML( $xmlStr );

    // add all Ingredient Sections from xmlStr as children of $parent
    $xmlList = $dom->getElementsByTagName( 'IngredientSection' );
    for ($i = $xmlList->length; --$i >= 0; ) {
      $elem = $xmlList->item($i);
      $parent->appendChild( $elem );
    }

    // add the parent to the $dom doc
    $dom->appendChild( $parent );

现在,当我点击$parent->appendChild( $elem );这一行时出现以下错误

Fatal error: Uncaught exception 'DOMException' with message 'Wrong Document Error'

字符串中的 XML 可能类似于以下示例。重要的一点是,可能有多个 IngredientSection,所有这些都需要附加到 $parent 元素。

<IngredientSection name="Herbed Cheese">
  <RecipeIngredient>
    <Quantity>2</Quantity>
    <Unit>cups</Unit>
    <Item>yogurt cheese</Item>
    <Note>(see Tip)</Note>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
  <RecipeIngredient>
    <Quantity>2</Quantity>
    <Unit/>
    <Item>scallions</Item>
    <Note>, trimmed and minced</Note>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
<IngredientSection name="Cracked-Wheat Crackers">
</IngredientSection>
  <RecipeIngredient>
    <Quantity>2</Quantity>
    <Unit>teaspoon</Unit>
    <Item>salt</Item>
    <Note/>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
  <RecipeIngredient>
    <Quantity>1 1/4</Quantity>
    <Unit>cups</Unit>
    <Item>cracked wheat</Item>
    <Note/>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
</IngredientSection>

【问题讨论】:

    标签: php xml domdocument


    【解决方案1】:

    这里有两种可能的解决方案:

    从源文档导入

    仅当 XML 字符串是有效文档时才有效。您需要导入文档元素或其任何后代。取决于您要添加到目标文档的部分。

    $xml = "<child>text</child>";
    
    $source = new DOMDocument();
    $source->loadXml($xml);
    
    $target = new DOMDocument();
    $root = $target->appendChild($target->createElement('root'));
    $root->appendChild($target->importNode($source->documentElement, TRUE));
    
    echo $target->saveXml();
    

    输出:

    <?xml version="1.0"?>
    <root><child>text</child></root>
    

    使用文档片段

    这适用于任何有效的 XML 片段。即使它没有根节点。

    $xml = "text<child>text</child>";
    
    $target = new DOMDocument();
    $root = $target->appendChild($target->createElement('root'));
    
    $fragment = $target->createDocumentFragment();
    $fragment->appendXml($xml);
    $root->appendChild($fragment);
    
    echo $target->saveXml();
    

    输出:

    <?xml version="1.0"?>
    <root>text<child>text</child></root>
    

    【讨论】:

    • 谢谢!我最终创建了第二个 DomDocument (您的第一个示例)。回想起来,使用文档片段似乎会减少开销。
    【解决方案2】:

    您需要使用-&gt;importNode() 而不是-&gt;appendChild()。您的 XML sn-ps 来自完全不同的 XML 文档,appendChild 将只接受属于 SAME xml 树的节点。 importNode() 将接受“外来”节点并将它们合并到主树中。

    【讨论】:

    • importNode() 不是DOMElement 上的方法。当我尝试$parent-&gt;appendChild( $dom-&gt;importNode( $elem, true ) ); 时,我得到相同的“错误文档错误”。你能举个例子吗?
    • 有趣。我的代码在遵循this post 的第二个答案后工作。看来我必须将 xml 字符串加载到第二个单独的 DOMDocument 并导入该元素。创建第二个 DOMDocument 似乎需要很多开销 - 我怀疑这就是 DOMDocumentFragment 的用途,但我需要找到一个示例。
    • -&gt;importNode() 是 DOMDocument 的一个方法。与createElement() 一样,它返回一个您可以附加的节点。所以“ìnstead of”应该换成“before”。
    猜你喜欢
    • 1970-01-01
    • 2020-02-19
    • 2011-07-30
    • 2012-05-06
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 2014-10-04
    相关资源
    最近更新 更多