php html 转xml,用PHP生成XML文档(转义字符)

用PHP生成XML文档(转义字符)

我正在从PHP脚本生成XML文档,并且需要转义XML特殊字符。我知道应该转义的字符列表; 但是正确的方法是什么?

应该使用反斜杠(\')来转义字符还是正确的方法?有内置的PHP函数可以为我处理此问题吗?

Tomas Jancik asked 2020-06-22T22:40:59Z

10个解决方案

36 votes

我创建了一个简单的函数,该函数使用XML中的五个“预定义实体”进行转义:

function xml_entities($string) {

return strtr(

$string,

array(

" "<",

">" => ">",

'"' => """,

"'" => "'",

"&" => "&",

)

);

}

用法示例演示:

$text = "Test & and encode :)";

echo xml_entities($text);

输出:

Test &amp; <b> and encode </b> :)

通过使用str_replace可以达到类似的效果,但是由于两次替换(未试用,不建议使用),它很脆弱:

function xml_entities($string) {

return str_replace(

array("&", "", '"', "'"),

array("&", "<", ">", """, "'"),

$string

);

}

Tomas Jancik answered 2020-06-22T22:42:07Z

34 votes

使用DOM类生成整个XML文档。 它将处理我们甚至不需要关心的编码和解码。

编辑:这被@Tchalvak批评:

DOM对象创建了一个完整的XML文档,它不容易将其自身编码为一个字符串。

错了,DOMDocument只能输出一个片段而不是整个文档:

$doc->saveXML($fragment);

这使:

Test & and encode :)

Test &amp; <b> and encode </b> :)

如:

$doc = new DOMDocument();

$fragment = $doc->createDocumentFragment();

// adding XML verbatim:

$xml = "Test & and encode :)\n";

$fragment->appendXML($xml);

// adding text:

$text = $xml;

$fragment->appendChild($doc->createTextNode($text));

// output the result

echo $doc->saveXML($fragment);

观看演示

Ionuț G. Stan answered 2020-06-22T22:41:33Z

17 votes

那get_html_translation_table()函数呢?

htmlspecialchars($input, ENT_QUOTES | ENT_XML1, $encoding);

注意:仅当您具有PHP 5.4.0或更高版本时,get_html_translation_table()标志才可用。

使用这些参数的get_html_translation_table()替换了以下字符:

get_html_translation_table()(与号)变成>

get_html_translation_table()(双引号)变成>

get_html_translation_table()(单引号)变为>

get_html_translation_table()(小于)变成>

get_html_translation_table()(大于)变为>

您可以使用get_html_translation_table()函数获取翻译表。

MarcDefiant answered 2020-06-22T22:43:02Z

13 votes

尝试解决XML实体问题,以这种方式解决:

htmlspecialchars($value, ENT_QUOTES, 'UTF-8')

Josh Sunderman answered 2020-06-22T22:43:22Z

5 votes

为了拥有有效的最终XML文本,您需要转义所有XML实体,并以与XML文档处理指令所声明的格式相同的编码来编写文本(<?xml行中的 “编码”)。 只要将重音字符编码为文档,就不必对其进行转义。

但是,在许多情况下,仅用iconv()转义输入可能会导致对实体进行双重编码(例如utf8_encode()将变为&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;

}

现在,您需要确保所有重音字符在XML文档编码中均有效。 我强烈建议始终以UTF-8编码XML输出,因为并非所有XML解析器都遵循XML文档处理指令编码。 如果您的输入可能来自其他字符集,请尝试使用iconv()。

有一种特殊情况,即您的输入可能来自以下一种编码: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;

}

Capilé answered 2020-06-22T22:43:56Z

2 votes

如果您需要正确的xml输出,则可以使用simplexml:

[HTTP://呜呜呜.PHP.net/manual/恩/simple XML element.as XML.PHP]

nubeiro answered 2020-06-22T22:44:21Z

1 votes

正确的转义是获得正确的XML输出的方法,但是您需要对属性和元素进行不同的转义处理。 (那是Tomas的回答是不正确的)。

我写/偷了一些Java代码,以区分属性和元素转义。 原因是XML解析器认为所有空白特别是属性中的空白。

将其移植到PHP上应该很简单(您可以使用Tomas Jancik的方法进行上述适当的转义)。 如果您使用UTF-8,则不必担心转义扩展实体。

如果您不想移植我的Java代码,可以查看XMLWriter,它基于流并且使用libxml,因此它应该非常有效。

Adam Gent answered 2020-06-22T22:44:55Z

0 votes

您可以使用以下方法:[http://php.net/manual/en/function.htmlentities.php]

这样,所有实体(html / xml)均被转义,您可以将字符串放入XML标签内

Alois Cochard answered 2020-06-22T22:45:19Z

-1 votes

基于sadeghj的解决方案,以下代码为我工作:

/**

* @param $arr1 the single string that shall be masked

* @return the resulting string with the masked characters

*/

function replace_char($arr1)

{

if (strpos ($arr1,'&')!== FALSE) { //test if the character appears

$arr1=preg_replace('/&/','&', $arr1); // do this first

}

// just encode the

if (strpos ($arr1,'>')!== FALSE) {

$arr1=preg_replace('/>/','>', $arr1);

}

if (strpos ($arr1,'

$arr1=preg_replace('/','<', $arr1);

}

if (strpos ($arr1,'"')!== FALSE) {

$arr1=preg_replace('/"/','"', $arr1);

}

if (strpos ($arr1,'\'')!== FALSE) {

$arr1=preg_replace('/\'/',''', $arr1);

}

return $arr1;

}

paderEpiktet answered 2020-06-22T22:45:39Z

-2 votes

function replace_char($arr1)

{

$arr[]=preg_replace('>','&gt', $arr1);

$arr[]=preg_replace('

$arr[]=preg_replace('"','&quot', $arr1);

$arr[]=preg_replace('\'','&apos', $arr1);

$arr[]=preg_replace('&','&amp', $arr1);

return $arr;

}

sadeghj answered 2020-06-22T22:45:54Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值