使用 PHP 的 SimpleXML 添加原始 XML

Prepending raw XML using PHP's SimpleXML

给定一个基础 $xml 和一个包含 <something> 标签的文件,该标签具有属性 children 和 children 的 children,我想将其附加为第一个 child 并将其所有 children 作为原始 XML.

原文XML:

<root>
    <people>
        <person>
            <name>John Doe</name>
            <age>47</age>
        </person>
        <person>
            <name>James Johnson</name>
            <age>13</age>
        </person>
    </people>
</root>

XML 在文件中:

<something someval="x" otherthing="y">
    <child attr="val"  ..> { some children and values ... }</child>
    <child attr="val2" ..> { some children and values ... }</child>
            ...
</something>

结果XML:

<root>
    <something someval="x" otherthing="y">
        <child attr="val"  ..> { some children and values ... }</child>
        <child attr="val2" ..> { some children and values ... }</child>
            ...
    </something>
    <people>
        <person>
            <name>John Doe</name>
            <age>47</age>
        </person>
        <person>
            <name>James Johnson</name>
            <age>13</age>
        </person>
    </people>
</root>

这个标签将包含几个直接和递归的 children,因此通过简单XML 操作构建 XML 是不切实际的。此外,将其保存在文件中可以降低维护成本。

从技术上讲,它只是在前面加上 一个 child。问题是这个 child 会有其他 children 等等。

PHP addChild page 上有一条评论说:

$x = new SimpleXMLElement('<root name="toplevel"></root>');
$f1 = new SimpleXMLElement('<child pos="1">alpha</child>');

$x->{$f1->getName()} = $f1; // adds $f1 to $x

但是,这似乎没有将我的 XML 视为原始 XML,因此导致出现 &lt;&gt; 转义标签。几个关于名称空间的警告似乎也出现了。

我想我可以快速替换这些标签,但我不确定它是否会导致未来出现问题,而且感觉肯定不对。

手动破解 XML 不是一种选择,也不是一个一个地添加 children。可以选择不同的库。

关于如何让它工作的任何线索?

谢谢!

真的不确定这是否可行。试试这个或否决这个,但我希望它有所帮助。使用 DOMDocument (Reference)

<?php
$xml = new DOMDocument();
$xml->loadHTML($yourOriginalXML);
$newNode = DOMDocument::createElement($someXMLtoPrepend);
$nodeRoot = $xml->getElementsByTagName('root')->item(0);
$nodeOriginal = $xml->getElementsByTagName('people')->item(0);
$nodeRoot->insertBefore($newNode,$nodeOriginal);

$finalXmlAsString = $xml->saveXML();
?>

有时候 UTF-8 会出问题,那么试试这个:

<?php
$xml = new DOMDocument();
$xml->loadHTML(mb_convert_encoding($yourOriginalXML, 'HTML-ENTITIES', 'UTF-8'));
$newNode = DOMDocument::createElement(mb_convert_encoding($someXMLtoPrepend, 'HTML-ENTITIES', 'UTF-8'));
$nodeRoot = $xml->getElementsByTagName('root')->item(0);
$nodeOriginal = $xml->getElementsByTagName('people')->item(0);
$nodeRoot->insertBefore($newNode,$nodeOriginal);

$finalXmlAsString = $xml->saveXML();
?>