PHP DOMDocument:如何合并一个xml字符串


PHP DOMDocument: how to incorporate a string of xml?

我正在构建一个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>

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

从源文档导入

只有当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>

您需要使用->importNode()而不是->appendChild()。您的XML片段来自一个完全不同的XML文档,appendChild将只接受属于SAME XML树的节点。importNode()将接受"外部"节点,并将它们合并到主树中。