如何使用 xquery 查找节点并向其添加 Child


How to use xquery to find node and addChild to it?

是否可以使用 xpath/xquery 查询特定的 xml 节点,然后向其导入/添加子节点?

示例(取自 http://codepad.org/gJ1Y2LjM 的代码,在类似的问题中提出,但不相同):

1.我想添加一个数组

$book = array('isbn'=>123456789099, 'title' => 'Harry Potter 3', 'author' => 'J K. Rowling', 'edition' => '2007');

阿拉伯数字。到现有 XML。

$doc = new DOMDocument();
$doc->loadXML('<?xml version="1.0"?>
<books>
    <book>
        <isbn>123456789098</isbn>
        <title>Harry Potter</title>
        <author>J K. Rowling</author>
        <edition>2005</edition>
    </book>
    <book>
        <placeItHere></placeItHere>
        <isbn>1</isbn>
        <title>stuffs</title>
        <author>DA</author>
        <edition>2014</edition>
    </book>
</books>');

3.为此,使用以下片段。

$fragment = $doc->createDocumentFragment();
$fragment->appendXML("    <book>
<isbn>{$book['isbn']}</isbn>
        <title>{$book['title']}</title>
        <author>{$book['author']}</author>
        <edition>{$book['edition']}</edition>
    </book>
");

4.但是,我几乎在互联网上找到的所有示例都没有将其附加到根节点:

$doc->documentElement->appendChild($fragment);

5.我想将它(p.ex)附加到/books/book/placeItHere中找到的节点,而不是使用getElementbyId或tagName,而是xpath/xquery。我试过了

$xp = new domxpath($doc);
$parent = $xp->query("books/book/placeItHere");

到达节点,但从未设法将其用作父节点。

问:如何使用该位置追加子$fragment?可能吗?

**YOUR BEAUTIFUL MAGIC**

最后我会保存它。

echo $doc->saveXML();

谢谢你能给我的任何帮助。

几个问题:

  1. 您的 xpath 表达式应/books/book/placeItHere(带有前导/)。
  2. DOMXPath::query()返回一个 DOMNodeList 而不是 DOMNode,所以你需要从中获取你的item()

我很少建议使用文档片段,因为快速而松散地使用原始 XML 通常会导致问题。例如,如果您的书名包含与号appendXML()则会因解析器错误而废话。

相反,我建议createElement()createTextNode(),这将自动处理将&等内容转换为&amp;


例:

$xml = <<<'XML'
<?xml version="1.0"?>
<books>
    <book>
        <isbn>123456789098</isbn>
        <title>Harry Potter</title>
        <author>J K. Rowling</author>
        <edition>2005</edition>
    </book>
    <book>
        <placeItHere></placeItHere>
        <isbn>1</isbn>
        <title>stuffs</title>
        <author>DA</author>
        <edition>2014</edition>
    </book>
</books>
XML;
$book = [
    'isbn'    => 123456789099,
    'title'   => 'Harry Potter 3',
    'author'  => 'J K. Rowling',
    'edition' => '2007'
];
$dom = new DOMDocument();
$dom->formatOutput = true;
$dom->preserveWhiteSpace = false;
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$placeItHere = $xpath->query('/books/book/placeItHere')->item(0);
$newBook = $placeItHere->appendChild($dom->createElement('book'));
foreach ($book as $part => $value) {
    $element = $newBook->appendChild($dom->createElement($part));
    $element->appendChild($dom->createTextNode($value));
}
echo $dom->saveXML();

输出:

<?xml version="1.0"?>
<books>
  <book>
    <isbn>123456789098</isbn>
    <title>Harry Potter</title>
    <author>J K. Rowling</author>
    <edition>2005</edition>
  </book>
  <book>
    <placeItHere>
      <book>
        <isbn>123456789099</isbn>
        <title>Harry Potter 3</title>
        <author>J K. Rowling</author>
        <edition>2007</edition>
      </book>
    </placeItHere>
    <isbn>1</isbn>
    <title>stuffs</title>
    <author>DA</author>
    <edition>2014</edition>
  </book>
</books>