0

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

PHP 应用程序使用放置在元素标签中的 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 (即 string &egrave;eesu;)。

&egrave;是一个有效的 HTML 实体,但我知道 XML 只定义了一组最小的字符引用(&amp;&lt;等),并且 XML 期望所有其他字符都在其文档编码表示中,因此会拒绝&egrave;.

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

4

2 回答 2

2

XML 只有 5 个实体。解析为 html 实体会在某些字符上中断,因为它会在实体本身中创建一个未编码的 &。

使用此函数而不是 htmlentities() 来转义实体:

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

借用 Tomas Jancik 的回答类似的问题: Generating XML document in PHP (escape characters)

于 2012-06-26T23:55:17.340 回答
-1

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

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

于 2012-08-25T13:12:14.357 回答