我有这段代码:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
$strXml = '
<root>
<kid><div>ABC•></div></kid>
<kid2>DEF</kid2>
</root>';
$objXml = new SimpleXMLElement($strXml);
$arrNodes = $objXml->xpath('/root/*');
foreach($arrNodes as $objNode) {
/* @var $objNode SimpleXMLElement */
echo $objNode->asXML();
}
代码提取根的第一个子节点并显示内容。问题是html实体被转换为字符。代码是否有任何方式输出初始XML内容而没有任何转换?
答案 0 :(得分:1)
代码是否有任何方式输出初始XML内容而没有任何转换?
没有
旁白:你为什么关心?他们是同一个角色。
答案 1 :(得分:0)
SimpleXML / DOMDocument / etc将始终转换这些实体,因为编号实体不是有效的XML。
所以:
答案 2 :(得分:0)
这让我觉得这是一种非常奇怪的行为,而且我没有运气搜索信息。
它似乎影响了所有相关的XML stuff。值得注意的是,一旦解析了XML,字符就会存储为常规字符:
php > print_r($objXml);
SimpleXMLElement Object
(
[kid] => SimpleXMLElement Object
(
[div] => ABC•>
)
[kid2] => DEF
)
...当XML转换为文本时,它们被写为实体。我猜测所有东西都使用相同的内部例程来转换为文本。
如果你真的需要这个功能,你可以创建自己的功能来逃避角色,如下所示:
// function to escape some utf8 characters with xml character reference
function xmlCharEncode($string) {
$out = '';
$len = mb_strlen($string, 'UTF-8');
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($string, $i, 1, 'UTF-8');
$convmap = array(
60, 60, 0, 0xffff, // <
62, 62, 0, 0xffff, // >
38, 38, 0, 0xffff, // ampersand
// you may want to filter quotes or other characters here
127, 0xffff, 0, 0xffff, // everything after basic latin
);
$enc = mb_encode_numericentity($char, $convmap, 'UTF-8');
$out .= $enc;
}
return $out;
}
...然后使用XMLReader和XMLWriter使用自定义字符转义例程编写XML:
// read and write your xml string
$r = new XMLReader();
$w = new XMLWriter();
$r->xml($strXml);
$w->openMemory();
while($r->read()) {
switch ($r->nodeType) {
// write elements, attributes, and text nodes
case XMLReader::ELEMENT:
$w->startElement($r->name);
while ($r->moveToNextAttribute()) {
echo $w->outputMemory(true);
$w->writeAttribute($r->name, $r->value);
}
break;
case XMLReader::END_ELEMENT:
$w->endElement();
break;
case XMLReader::TEXT:
$w->writeRaw(xmlCharEncode($r->value)); // the magic happens here
break;
}
echo $w->outputMemory(true);
}
我并不是真的相信这是值得的,但至少你知道可以采取什么样的措施来实现这个目标。
顺便说一下,这将适用于您的原始示例。