为了确保我们在同一页面上,您有三种情况。
使用 addAttribute 将 & 符号插入到属性中
使用 addChild 将 & 符号插入到元素中
通过属性重载将 & 符号插入元素
这是2和3之间的差异让你感到困惑。为什么 addChild 不会自动转义 & 符号,而向对象添加属性并设置其值会自动转义 & 符号?
根据我的直觉,并受到这个错误的支持,这是一个深思熟虑的设计决定。属性重载 ($a->d = 'Five & Six';)旨在成为“为我转义与号”的做事方式。addChild 方法的意思是“添加我告诉您添加的内容”方法。因此,无论您需要哪种行为,SimpleXML都可以满足您的需求。
假设您有一个文本数据库,其中所有 & 符号都已转义。自动转义在这里对您不起作用。这就是你使用addChild的地方。或者假设您需要在文档中插入实体
$a = simplexml_load_string('<root></root>');
$a->b = 'This is a non-breaking space ';
$a->addChild('c','This is a non-breaking space ');
print $a->asXML();
这就是该错误中的PHP开发人员所提倡的。addChild 的行为旨在当您需要在文档中插入 & 符号而不对其进行转义时提供“更简单,更可靠”的支持。
当然,这确实给我们留下了我提到的第一种情况,即addAttribute方法。addAttribute 方法可转义与号。因此,我们现在可以将不一致声明为
- addAttribute 方法转义与号
- addChild 方法不转义与号
- 此行为有些不一致。用户期望 SimpleXML 上的方法以一致的方式转义是合理的。
这就暴露了 SimpleXML api 的真正问题。这里的理想情况是
- 元素对象上的属性重载对 & 符号进行转义
- 属性对象上的属性重载对 & 符号进行转义
- addChild 方法不转义与号
- addAttribute 方法不转义与号
但这是不可能的,因为 SimpleXML 没有属性对象的概念。addAttribute 方法是(似乎是?)添加属性的唯一方法。正因为如此,事实证明(似乎?SimpleXML 无法使用实体创建属性。
所有这些都揭示了简单XML 的悖论。这个API背后的想法是提供一种与复杂事物交互的简单方法。
该团队本可以添加一个 SimpleXMLAttribute 对象,但这是一个额外的复杂性层。如果需要多对象层次结构,请使用 DomDoument。
该团队本可以向 addAttribute 和 addChild 方法添加标志,但标志会使 API 更加复杂。
真正的教训是什么?也许简单很难,而在截止日期前简单更难。我不知道情况是否如此,但是对于SimpleXML,似乎有人从一个简单的想法开始(使用属性重载使XML文档的创建变得容易),然后随着问题/功能请求的出现进行调整。
实际上,我认为这里真正的教训是只使用JSON;)