我的RESTful WCF服务接受来自客户端的XML请求主体,大多数客户端是PHP应用程序。
PHP应用程序使用htmlentities()对其请求进行编码,htmlentities()位于元素标记内。例如,添加新用户帐户的请求可能如下所示:
$body = "<user>
<userName>" . htmlentities( $userName ) . "</userName>
</user>"
系统工作正常,它没有出现任何错误,直到今天。
我查看了日志,发现此请求失败了:
<user>
<userName>èeesu</userName>
</user>
,但有以下例外:
InvalidOperationException:“XML文档中存在错误(4,12)。” XmlException:“字符引用无效。第4行,第12位。”
(第4行,第12行,指的是<userName>
元素的InnerText(即字符串èeesu;
)。
è
是一个有效的HTML实体,但我理解XML只定义了一组最小的字符引用(&
,<
等),并且XML期望所有其他字符相反,它将在他们的文档编码表示中,因此将拒绝诸如è
之类的内容。
有人可以确认是这种情况吗?如果是这样,我怎样才能让PHP只编码特定于XML的实体而不是HTML实体?
答案 0 :(得分:2)
XML只有5 entities。解析为html实体会破坏某些字符,因为它会创建一个未编码的&amp;在实体本身。
使用此函数代替htmlentities()来转义实体:
function xmlentities($string) {
return str_replace(array("&", "<", ">", "\"", "'"),
array("&", "<", ">", """, "'"), $string);
}
从Tomas Jancik借来的类似问题: Generating XML document in PHP (escape characters)
答案 1 :(得分:-1)
我改为使用htmlspecialchars( $userName, ENT_XML1 )
,它只会将最少的字符转换为实体,而不会对它们进行不必要的编码。
@ Jordan的str_replace函数做同样的事情,但是当你对它进行基准测试时它会更慢,因为htmlspecialchars是一个原生函数。