我有这个xml(必须通过HTML剪切/粘贴)。
<tr>
<td>http://www.example.co.uk/the-view-from-22/feed/</td>
<td>Example Blogs » The View from 22 » Example Blogs</td>
<td>http://blogs.example.co.uk/</td>
<td><![CDATA[Listen: The Example’s verdict on the debate]]></td>
<td>http://blogs.example.co.uk/coffeehouse/2015/04/podcast-special-the-debate/</td>
</tr>
它正被加载到XML dom文档
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML( $xml->asXML() );
return $dom->saveXML();
但这引发了关于&amp; rsquo的错误;实体没有被定义。
警告:DOMDocument :: loadXML()[domdocument.loadxml]:实体'rsquo'未在实体中定义,...
正如在CDATA部分中一样,我期望DOMDocument将其视为文本而忽略它......但它没有......有没有解决方法呢?
数据被直接从视图中的mysql数据库中提取出来,因此首先“修复”的空间不大 - 我在视图的select子句中添加了CDATA,这是我尝试的修复!
修改 根据以下建议追踪它(干杯!)
使用$ xml-&gt; addChild($ key,$ value)加载数据,但$ value的格式正如您推测的那样编码。
所以我只想尝试一下......
How to write CDATA using SimpleXmlElement?
它的确有效 - 我现在正在加载orignal doc: -
if (strpos(strtoupper($value),'<![CDATA[') === 0 && strpos(strrev($value),'>]]') === 0) {
$child = $xml->addChild( $key );
$node = dom_import_simplexml($child);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection(substr($value,9,strlen($value)-12)));
//simple key/value child pair
} else {
$xml->addChild( $key, $value );
}
答案 0 :(得分:0)
如果它只有一个’
而不是大量的特殊字符,你可以尝试替换它。
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$xml = $xml->asXML();
$xml = str_replace('’', '’', $xml);
$dom->loadXML($xml);
return $dom->saveXML();
真正的问题是,’
是如何进入您的数据库的。
在插入之前修复它...然后你可以拉出格式良好的XML。 https://stackoverflow.com/a/3142636/1163786
或使rsquo成为有效的实体:
<!DOCTYPE ROOT_XML_ELEMENT [ <!ENTITY rsquo "’"> ]>
如果您的内容是UTF-8,只需将其替换为:
(我认为)最初的问题就是这个问题:
警告:实体'rsquo'未在实体中定义,行:...
<?php
$xml = <<<XML
<tr>
<td>Listen: The Example’s verdict on the debate></td>
</tr>
XML;
$doc = new DOMDocument();
$doc->presverWhitespace = false;
$doc->formatOutput = true;
$doc->loadXML($xml);
echo $doc->saveXML();
因为实体'rsquo'不是有效的XML,所以会弹出错误。现在,pperrin通过添加“CDATA修复”解决了这个问题。这就是我理解这个问题的方式。
您不需要CDATA - 如果您
答案 1 :(得分:0)
正如我用my example code所证明的那样,我无法重现你的问题。因此,我得出的结论是,您必须具有双重编码,并且双重编码数据是XML解析器扼流的地方,并且正确地为您提供警告。只是由于双重编码,这并不是立即可见的。
对数据进行一次解码,以便对其进行正确的XML编码。然后DOMDocument可以轻松加载它。
旧答案(对于通过搜索引擎来到这里的用户仍然有用):
我怀疑您的问题是$xml->asXML()
,因为CDATA部分不会产生该错误。
首先有一种更好的方法可以转换为DOMDocument:
$dom = dom_import_simplexml($xml)->documentElement;
这也应该保留CDATA部分的编码(不是100%肯定)。对于您的格式化,您可能需要重新加载文档,但也许您不需要。尝试
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$result = $dom->saveXML();
如果结果还不是您想要的预期漂亮打印格式, 你可以从dom重新加载文件:
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($dom->saveXML());
$result = $dom->saveXML();
我希望因为这是DOMDocument,所以以前的CDATA编码字符与实体类似没有问题。
转换函数dom_import_simplexml()
is in the manual以及SimpleXML和DOM共享公共虚拟接口,如果要在DOM和SimpleXML之间切换,反之亦然,使用它应该是首选方式。