如何将 SimpleXMLElement 节点添加为子元素?

How to add SimpleXMLElement node as a child element?

我有这个 PHP 代码。 $target_xml$source_xml 变量是 SimpleXMLElement 个对象:

$target_body = $target_xml->children($this->namespaces['main']);
$source_body = $source_xml->children($this->namespaces['main']);

foreach ($source_body as $source_child) {
    foreach ($source_child as $p) {
        $target_body->addChild('p', $p, $this->namespace['main']);
    }
}

$p中会是这样的XML代码:

<w:p w:rsidR="009F3A42" w:rsidRPr="009F3A42" w:rsidRDefault="009F3A42" w:rsidP="009F3A42">
    <w:pPr>
        <w:pStyle w:val="NormlWeb"/>
        // .... here is more xml tags
    </w:pPr>
    <w:r w:rsidRPr="009F3A42">
        <w:rPr>
            <w:rFonts w:ascii="Open Sans" w:hAnsi="Open Sans" w:cs="Open Sans"/>
            <w:b/>
            <w:color w:val="000000"/>
            <w:sz w:val="21"/>
            <w:szCs w:val="21"/>
        </w:rPr>
        <w:t>Lorem ipsum dolor sit amet...</w:t>
    </w:r>
    <w:bookmarkStart w:id="0" w:name="_GoBack"/>
    <w:bookmarkEnd w:id="0"/>
</w:p>

我上面的 PHP 代码只会将此 XML 代码添加到目标文档:

<w:p/>

所以所有的子节点都丢失了。

如何添加具有自己子节点的子节点?

SimpleXMLElement::addChild 方法只接受简单值。但在这种情况下,您正试图添加另一个 SimpleXMLElement 对象。

你可以看看这个link,建议使用DOM

这是dom_import_simplexml

的官方函数文档https://www.php.net/manual/en/function.dom-import-simplexml.php

您的代码应如下所示:

<?php
$target_xml = new DOMDocument('1.0');

$source_body = $source_xml->children($this->namespaces['main']);

foreach ($source_body as $source_child) {
    foreach ($source_child as $p) {
        $dom_sxe = dom_import_simplexml($p);
        // don't forget to handle your errors
        $target_xml->appendChild($dom_sxe);
    }
}

//you get back your target xml here
echo $target_xml->saveXML();

SimpleXML 适用于基本的东西,但缺乏 DOMDocument 的控制(和复杂性)。

将内容从一个文档复制到另一个文档时,您必须做三件事(对于 SimpleXML),首先是将其转换为 DOMElement,然后使用 importNode() 将其导入目标文档以 true 作为第二个参数说做一个深拷贝。这只是使其对目标文档可用,并没有实际放置内容。这是使用 appendChild() 和新导入的节点完成的...

// Convert target SimpleXMLElement to DOMElement
$targetImport = dom_import_simplexml($target_body);

foreach ($source_body as $source_child) {
    foreach ($source_child as $p) {
        // Convert SimpleXMLElement to DOMElement
        $sourceImport = dom_import_simplexml($p);
        // Import the new node into the target document
        $import = $targetImport->ownerDocument->importNode($sourceImport, true);
        // Add the new node to the correct part of the target
        $targetImport->appendChild($import);
    }
}