我编写了一个简短的PHP脚本来获取现有的XML文件,找到一个节点并将其更改为新值。必须将新值包装到CDATA块中。这工作正常,但<>字符将替换为各自的HTML实体。这破坏了我在Java中的XML验证。
Employee emp = new Manager();
这是新test.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();
?>
我真的需要&lt;&gt;字符而不是HTML实体。我怎么能做到这一点?
更新: 我根据建议使用了createCDATASection(),但是当我尝试将其保存为节点值时,它不起作用(我只是得到一个空白页面)。如果我将它附加到DOM,它可以工作,但这对我没有好处。
<?xml version="1.0"?>
<Root>
<FirstNode>
<SomeNode><![CDATA[whatever]]></SomeNode>
</FirstNode>
</Root>
答案 0 :(得分:4)
除了空字符串外,不要使用DOMNode::$nodeValue
来写入值。逃跑打破了。创建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()的结果是附加节点。所以它可以与create:
结合使用$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"><content><![CDATA[<content>]]></nodename>
如果您想修改现有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部分禁用编码/转义功能。
答案 1 :(得分:2)
我们说你的test.xml
文件是
<?xml version="1.0"?>
<Root>
<FirstNode>
<SomeNode>a</SomeNode>
</FirstNode>
</Root>
你有两种可能性:
或者你想要添加SomeNode
<SomeNode>
a
<![CDATA[whatever]]>
</SomeNode>
然后你就可以这样做:
$cdata = $doc->createCDATASection( 'whatever' );
$doc->getElementsByTagName("SomeNode")
->item(0)
->appendChild($cdata);
或者您想在SomeNode中替换
<SomeNode>
<![CDATA[whatever]]>
</SomeNode>
然后你可以这样做:
$cdata = $doc->createCDATASection( 'whatever' );
$oldNode = $doc->getElementsByTagName("SomeNode")
->item(0);
$oldNode->parentNode
->replaceChild($cdata,$oldNode);