我正在向外部供应商发送XML文档,其中一个在解析XML时遇到问题,因为XML内容中存在单引号和双引号。我知道根据官方的XML规范,这些只需要在属性中使用时进行转义,但我认为扩展PHP的SimpleXMLElement以使其转义为引用并不会太困难。此情况并非如此。我的第一次尝试是这样的:
<?php
class BetterXMLElement extends SimpleXMLElement
{
public function __set($name, $value)
{
echo "called __set with $name and $value";
$this->addChild($name, $value);
}
public function addChild($name, $value=null, $ns=null)
{
$new_value = strtr($value, [
'&' => '&',
'"' => '"',
"'" => ''',
]);
echo "New Value: $new_value\n";
parent::addChild($name, $new_value, $ns);
}
}
$xml = new BetterXMLElement('<?xml version="1.0" encoding="UTF-8"?><TRANSACTION></TRANSACTION>');
$xml->COST = "apos: ', amp: &, quot: \"";
$xml->addChild('PRODUCT', "apos: ', amp: &, quot: \"");
echo $xml->asXML();
以上代码输出:
New Value: apos: ', amp: &, quot: "
<?xml version="1.0" encoding="UTF-8"?>
<TRANSACTION><COST>apos: ', amp: &, quot: "</COST><PRODUCT>apos: ', amp: &, quot: "</PRODUCT></TRANSACTION>
这对我来说是:
__set
中的回声没有被调用,正如我预期的那样,当我设置COST时。为什么这不起作用?答案 0 :(得分:0)
不要使用简单的xml - 这是垃圾!
而是尝试DOMDocument()!
$dom = new DOMDocument();
$hello = $dom->createElement('hello');
$hello->setAttribute('such', 'wow');
$text = new DOMText('This & That');
$hello->appendChild($text);
$dom->appendChild($hello);
echo $dom->saveXML();
这将创建以下内容:
<?xml version="1.0"?> <hello such="wow">This & That</hello>
答案 1 :(得分:0)
据我所知,由于libxml2的固有设计,没有干净的内置方法来完成我需要使用SimpleXMLElement或DOMDocument。我最终在XML处理之前用占位符替换必要的字符(例如,单引号被替换为“{quot}”),然后在XML输出中使用适当的HTML实体交换这些占位符。
另外,正如先前评论中指出的那样,SimpleXMLElement不是普通的PHP类,这就是我的覆盖尝试失败的原因。