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 可能类似于以下示例。重要的一点是,可能有多个IngredientSections,都需要追加到$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>
您需要使用 ->importNode()
而不是 ->appendChild()
。您的 XML 片段来自完全不同的 XML 文档,并且 appendChild
将只接受属于同一 xml 树的节点。 importNode()
将接受 "foreign" 个节点并将它们合并到主树中。
这里有两个可能的解决方案:
从源文档导入
这仅在 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>
我正在构建一个 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 可能类似于以下示例。重要的一点是,可能有多个IngredientSections,都需要追加到$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>
您需要使用 ->importNode()
而不是 ->appendChild()
。您的 XML 片段来自完全不同的 XML 文档,并且 appendChild
将只接受属于同一 xml 树的节点。 importNode()
将接受 "foreign" 个节点并将它们合并到主树中。
这里有两个可能的解决方案:
从源文档导入
这仅在 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>