我正在从PHP脚本生成XML文档,我需要转义XML特殊字符.我知道应该转义的字符列表; 但是这样做的正确方法是什么?
是否应该使用反斜杠(\')或正确的方式转义字符?是否有任何内置的PHP函数可以为我处理这个?
Tom*_*cik 36
我创建了一个简单的函数,它使用XML中的五个"预定义实体"进行转义:
function xml_entities($string) {
return strtr(
$string,
array(
"<" => "<",
">" => ">",
'"' => """,
"'" => "'",
"&" => "&",
)
);
}
Run Code Online (Sandbox Code Playgroud)
用法示例演示:
$text = "Test & <b> and encode </b> :)";
echo xml_entities($text);
Run Code Online (Sandbox Code Playgroud)
输出:
Test &amp; <b> and encode </b> :)
Run Code Online (Sandbox Code Playgroud)
通过使用可以实现类似的效果str_replace
但由于双重替换它是脆弱的(未经测试,不推荐):
function xml_entities($string) {
return str_replace(
array("&", "<", ">", '"', "'"),
array("&", "<", ">", """, "'"),
$string
);
}
Run Code Online (Sandbox Code Playgroud)
Ion*_*tan 34
使用DOM类生成整个XML文档.它将处理我们甚至不想关心的编码和解码.
编辑:这被@Tchalvak批评:
DOM对象创建一个完整的XML文档,它不容易仅仅为它自己编码一个字符串.
哪个错了,DOMDocument可以正确输出一个片段而不是整个文档:
$doc->saveXML($fragment);
Run Code Online (Sandbox Code Playgroud)
这使:
Test & <b> and encode </b> :)
Test &amp; <b> and encode </b> :)
Run Code Online (Sandbox Code Playgroud)
如:
$doc = new DOMDocument();
$fragment = $doc->createDocumentFragment();
// adding XML verbatim:
$xml = "Test & <b> and encode </b> :)\n";
$fragment->appendXML($xml);
// adding text:
$text = $xml;
$fragment->appendChild($doc->createTextNode($text));
// output the result
echo $doc->saveXML($fragment);
Run Code Online (Sandbox Code Playgroud)
见演示
Mar*_*ant 17
htmlspecialchars()
功能怎么样?
htmlspecialchars($input, ENT_QUOTES | ENT_XML1, $encoding);
Run Code Online (Sandbox Code Playgroud)
注意: 该ENT_XML1
标志仅在PHP 5.4.0或更高版本时可用.
htmlspecialchars()
使用这些参数替换以下字符:
&
(&符号)变成了 &
"
(双引号)成为 "
'
(单引号)成为 '
<
(小于)成为 <
>
(大于)成为 >
您可以使用该get_html_translation_table()
功能获取转换表.
小智 13
试图处理XML实体问题,以这种方式解决:
htmlspecialchars($value, ENT_QUOTES, 'UTF-8')
Run Code Online (Sandbox Code Playgroud)
为了获得有效的最终XML文本,您需要转义所有XML实体,并使用与XML文档处理指令相同的编码来编写文本(行中的"编码" <?xml
).只要将重音字符编码为文档,就不需要对其进行转义.
但是,在许多情况下,简单地转义输入htmlspecialchars
可能会导致双重编码的实体(例如é
会变成&eacute;
),所以我建议首先解码html实体:
function xml_escape($s)
{
$s = html_entity_decode($s, ENT_QUOTES, 'UTF-8');
$s = htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
return $s;
}
Run Code Online (Sandbox Code Playgroud)
现在,您需要确保所有重音字符在XML文档编码中都有效.我强烈建议始终以UTF-8编码XML输出,因为并非所有XML解析器都遵循XML文档处理指令编码.如果您的输入可能来自不同的字符集,请尝试使用utf8_encode()
.
有一个特殊情况,你的输入可能来自以下编码之一:ISO-8859-1,ISO-8859-15,UTF-8,cp866,cp1251,cp1252和KOI8-R - PHP将它们全部视为同样,但它们之间存在一些细微差别 - 其中一些甚至iconv()
无法处理.我只能通过补充utf8_encode()
行为来解决这个编码问题:
function encode_utf8($s)
{
$cp1252_map = array(
"\xc2\x80" => "\xe2\x82\xac",
"\xc2\x82" => "\xe2\x80\x9a",
"\xc2\x83" => "\xc6\x92",
"\xc2\x84" => "\xe2\x80\x9e",
"\xc2\x85" => "\xe2\x80\xa6",
"\xc2\x86" => "\xe2\x80\xa0",
"\xc2\x87" => "\xe2\x80\xa1",
"\xc2\x88" => "\xcb\x86",
"\xc2\x89" => "\xe2\x80\xb0",
"\xc2\x8a" => "\xc5\xa0",
"\xc2\x8b" => "\xe2\x80\xb9",
"\xc2\x8c" => "\xc5\x92",
"\xc2\x8e" => "\xc5\xbd",
"\xc2\x91" => "\xe2\x80\x98",
"\xc2\x92" => "\xe2\x80\x99",
"\xc2\x93" => "\xe2\x80\x9c",
"\xc2\x94" => "\xe2\x80\x9d",
"\xc2\x95" => "\xe2\x80\xa2",
"\xc2\x96" => "\xe2\x80\x93",
"\xc2\x97" => "\xe2\x80\x94",
"\xc2\x98" => "\xcb\x9c",
"\xc2\x99" => "\xe2\x84\xa2",
"\xc2\x9a" => "\xc5\xa1",
"\xc2\x9b" => "\xe2\x80\xba",
"\xc2\x9c" => "\xc5\x93",
"\xc2\x9e" => "\xc5\xbe",
"\xc2\x9f" => "\xc5\xb8"
);
$s=strtr(utf8_encode($s), $cp1252_map);
return $s;
}
Run Code Online (Sandbox Code Playgroud)