WCF / PHP - XML Parser无法处理HTML实体?

时间:2012-06-26 22:39:31

标签: php xml wcf

我的RESTful WCF服务接受来自客户端的XML请求主体,大多数客户端是PHP应用程序。

PHP应用程序使用htmlentities()对其请求进行编码,htmlentities()位于元素标记内。例如,添加新用户帐户的请求可能如下所示:

$body = "<user>
    <userName>" . htmlentities( $userName ) . "</userName>
</user>"

系统工作正常,它没有出现任何错误,直到今天。

我查看了日志,发现此请求失败了:

<user>
    <userName>&egrave;eesu</userName>
</user>

,但有以下例外:

InvalidOperationException:“XML文档中存在错误(4,12)。” XmlException:“字符引用无效。第4行,第12位。”

(第4行,第12行,指的是<userName>元素的InnerText(即字符串&egrave;eesu;)。

&egrave;是一个有效的HTML实体,但我理解XML只定义了一组最小的字符引用(&amp;&lt;等),并且XML期望所有其他字符相反,它将在他们的文档编码表示中,因此将拒绝诸如&egrave;之类的内容。

有人可以确认是这种情况吗?如果是这样,我怎样才能让PHP只编码特定于XML的实体而不是HTML实体?

2 个答案:

答案 0 :(得分:2)

XML只有5 entities。解析为html实体会破坏某些字符,因为它会创建一个未编码的&amp;在实体本身。

使用此函数代替htmlentities()来转义实体:

function xmlentities($string) {
return str_replace(array("&", "<", ">", "\"", "'"),
    array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;"), $string);
}

从Tomas Jancik借来的类似问题: Generating XML document in PHP (escape characters)

答案 1 :(得分:-1)

我改为使用htmlspecialchars( $userName, ENT_XML1 ),它只会将最少的字符转换为实体,而不会对它们进行不必要的编码。

@ Jordan的str_replace函数做同样的事情,但是当你对它进行基准测试时它会更慢,因为htmlspecialchars是一个原生函数。