php输出xml产生解析错误“'”

时间:2010-06-29 16:08:43

标签: php xml xml-parsing

是否有任何函数可用于解析任何字符串以确保它不会导致xml解析问题?我有一个php脚本输出一个xml文件,其中包含从表单中获取的内容。

问题是,除了来自php表单的通常字符串检查之外,一些用户文本会导致xml解析错误。我特别面对这个“’”。这是我得到的错误Entity 'rsquo' not defined

有没有人有为xml输出编码文本的经验?

谢谢!


一些澄清: 我正在从xml文件中的表单输出内容,然后由javascript解析。

我处理所有表单输入:htmlentities(trim($_POST['content']), ENT_QUOTES, 'UTF-8');

当我想将此内容输出到xml文件中时,我应该如何对其进行编码,使其不会引发xml解析错误?

到目前为止,以下2个解决方案有效:

1)echo '<content><![CDATA['.$content.']]></content>';

2)echo '<content>'.htmlspecialchars(html_entity_decode($content, ENT_QUOTES, 'UTF-8'),ENT_QUOTES, 'UTF-8').'</content>'."\n";

上述2种解决方案是否安全?哪个更好?

谢谢,抱歉没有提前提供这些信息。

8 个答案:

答案 0 :(得分:7)

你采取错误的方式 - 不要寻找一个不会给你错误的解析器。而是尝试使用格式良好的xml。

您是如何从用户那里获得&rsquo;的?如果他确实键入了它,你就没有正确处理输入 - 例如你应该逃避&amp;到&amp;。如果您将实体放在那里(可能代替一些撇号),可以在DTD(<!ENTITY rsquo "&x2019;">)中定义它,或者使用数字符号(&#x2019;)来编写实体,因为几乎每一个都是命名实体是HTML的一部分。正如Gumbo指出的那样,XML只定义了几个基本的。

编辑基于问题的补充:

  • 在#1中,如果用户输入]]> <°)))><,您就会出现问题,从而逃避内容。
  • 在#2中,你正在进行编码和解码,这会产生$ content的原始值。解码不应该是必要的(如果你不希望用户发布像这样的值&amp;应该被解释为&amp;)。

如果你使用带有ENT_QUOTES的htmlspecialchars(),它应该没问题,但请参阅how Drupal does it

答案 1 :(得分:4)

html_entity_decode($string, ENT_QUOTES, 'UTF-8')

答案 2 :(得分:4)

将值包含在CDATA标记内。

<message><![CDATA[&rsquo;]]></message>

来自w3schools site

  

像“&lt;”这样的字符和“&amp;”在XML元素中是非法的。

     

“&LT;”将生成错误,因为解析器将其解释为新元素的开头。

     

“&安培;”将生成错误,因为解析器将其解释为字符实体的开头。

     

有些文字,比如JavaScript代码,包含很多“&lt;”或“&amp;”字符。为避免错误,脚本代码可以定义为CDATA。

     

解析器会忽略CDATA部分内的所有内容。

答案 3 :(得分:3)

问题是你的htmlentities函数正在做它应该做的事情 - 从字符生成HTML实体。然后,您将这些插入到未定义HTML实体的XML文档中(&rsquo;之类的内容是特定于HTML的。)

处理此问题的最简单方法是保持所有输入原始(即不用htmlentities解析),然后使用PHP的XML函数生成XML。

这将确保所有文本都已正确编码,并且您的XML格式正确。

示例:

$user_input = "...<>&'";

$doc = new DOMDocument('1.0','utf-8');

$element = $doc->createElement("content");
$element->appendChild($doc->createTextNode($user_input));

$doc->appendChild($element);

答案 4 :(得分:1)

我遇到类似的问题,我需要添加到XML的数据已经被我的代码作为htmlentities()返回(不是像这样的数据库)。

我用过:

$doc = new DOMDocument('1.0','utf-8');    
$element = $doc->createElement("content");    
$element->appendChild($doc->createElement('string', htmlspecialchars(html_entity_decode($string, ENT_QUOTES, 'UTF-8'), ENT_XML1, 'UTF-8')));
$doc->appendChild($element);

或者它是否已经在htmlentities() 只是下面应该工作

$doc = new DOMDocument('1.0','utf-8');

$element = $doc->createElement("content");       
$element->appendChild($doc->createElement('string', htmlspecialchars($string, ENT_XML1, 'UTF-8')));
$doc->appendChild($element);

基本上使用带有ENT_XML1的htmlspecialchars应该将用户估算的数据导入XML安全数据(并且对我来说很好):

htmlspecialchars($string, ENT_XML1, 'UTF-8');

答案 5 :(得分:0)

使用htmlspecialchars()将解决您的问题。请参阅下面的帖子。

PHP - Is htmlentities() sufficient for creating xml-safe values?

答案 6 :(得分:0)

htmlspecialchars($trim($_POST['content'], ENT_XML1, 'UTF-8');

应该这样做。

答案 7 :(得分:0)

这对我有用。遇到同样问题的人可以试试这个。

htmlentities($string, ENT_XML1)

带特殊字符转换。

htmlspecialchars(htmlentities($string, ENT_XML1))