gpt4 book ai didi

php - 在 PHP 中使用 saveXML 保存 CDATA

转载 作者:可可西里 更新时间:2023-10-31 22:42:23 24 4
gpt4 key购买 nike

我写了一个简短的 PHP 脚本来抓取现有的 XML 文件,找到一个节点并将其更改为新值。新值必须包装到 CDATA block 中。这工作正常,但是 <> 字符被替换为它们各自的 HTML 实体。这会破坏我在 Java 中的 XML 验证。

<?php
$fileName = "whatever";

$doc = new DOMDocument();
$doc->load('test.xml');
$doc->getElementsByTagName("SomeNode")->item(0)->nodeValue = "<![CDATA[".$fileName."]]>";
header('Content-type: text/xml');
$doc->save("test.xml");
echo $doc->saveXML();

?>

这是新的 test.xml 的来源:

<?xml version="1.0"?>
<Root>
<FirstNode>
<SomeNode>&lt;![CDATA[whatever]]&gt;</SomeNode>
</FirstNode>
</Root>

我真的需要 <> 字符而不是它们的 HTML 实体。我怎样才能做到这一点?

更新:我按照建议使用了 createCDATASection(),但是当我尝试将它保存为节点值时它不起作用(我只得到一个空白页)。如果我将它附加到 DOM,它会起作用,但这对我没有好处。

$cdata = $doc->createCDATASection( 'whatever' ));
$doc->getElementsByTagName("SomeNode")->item(0)->nodeValue = $cdata;

最佳答案

不要使用DOMNode::$nodeValue 写入值,空字符串除外。它的转义被打破了。节点文本内容的“官方”属性是 DOMNode::$textContent

创建 XML 节点有 3 个步骤:

  1. 创建节点
  2. 附加节点
  3. 修改节点(可选)

创建节点

这取决于您要创建的节点。

一个元素节点:

$element = $document->createElement('nodename');

或者一个文本节点:

$text = $document->createTextNode('<content>');

或 CDATA 部分:

$cdata = $document->createCDATASection('<content>');

附加节点

现在您有了一个节点,您可以将它附加到文档或父元素节点。

$document->appendChild($element);
$element->appendChild($text);
$element->appendChild($cdata);

appendChild() 的结果是追加的节点。所以它可以结合创建:

$element = $document->appendChild($document->createElement('nodename'));

修改节点

这主要是针对元素节点完成的。您可以添加属性和子节点。

$element->setAttribute('attr', 'value');

例子

// create the document 
$document = new DOMDocument();

// create the document element node and append it
$element = $document->appendChild($document->createElement('nodename'));
// set an attribute on the element node
$element->setAttribute('attr', 'value');
// add a text node to the element node (escape <>)
$element->appendChild($document->createTextNode('<content>'));
// add a CDATA section to the element node (do not escape <>)
$element->appendChild($document->createCDATASection('<content>'));

echo $document->saveXml();

输出:

<?xml version="1.0"?>
<nodename attr="value">&lt;content&gt;<![CDATA[<content>]]></nodename>

修改现有的 XML

如果您想修改现有的 XML,您需要先获取节点。最有效的方法是 XPath。

它允许您获取节点。与 DOMDocument::getElementByTagName() 一样,它将返回一个节点列表,但它更加具体和强大。

例子

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXPath($document);

foreach ($xpath->evaluate('/Root/FirstNode/SomeNode[1]') as $someNode) {
$someNode->nodeValue = '';
$someNode->appendChild($document->createCDATASection('<content>'));
}
echo $document->saveXml();

输出:

<?xml version="1.0"?>
<Root>
<FirstNode>
<SomeNode><![CDATA[<content>]]></SomeNode>
</FirstNode>
</Root>

$someNode->nodeValue = ''。删除元素的所有子节点。这里没有实际内容,因此转义错误不相关。删除子项后,您可以附加一个包含所需内容的新 CDATA 部分。

提示:尽可能使用文本节点,而不是 CDATA 部分。 CDATA 部分禁用编码/转义功能。

关于php - 在 PHP 中使用 saveXML 保存 CDATA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30177892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com