为了确保我们在同一页面上,您有三种情况。
使用 addAttribute 将 & 符号插入属性
使用 addChild 将 & 符号插入元素
通过属性重载将&符号插入元素
2 和 3 之间的差异让您感到困惑。为什么 addChild 不会自动转义 & 符号,而向对象添加属性并设置其值确实会自动转义 & 符号?
基于我的直觉,并受到this bug 的鼓舞,这是一个深思熟虑的设计决定。属性重载 ($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();
这就是那个 bug 中的 PHP 开发人员所提倡的。当您需要在文档中插入 & 符号而不被转义时,addChild 的行为旨在提供“不那么简单、更健壮”的支持。
当然,这确实给我们留下了我提到的第一种情况,addAttribute 方法。 addAttribute 方法确实 转义和符号。因此,我们现在可以将不一致声明为
- addAttribute 方法对 & 符号进行转义
- addChild 方法不会转义 & 符号
- 此行为有些不一致。用户期望 SimpleXML 上的方法以一致的方式转义是合理的
这暴露了 SimpleXML api 的真正问题。这里的理想情况是
- 元素对象上的属性重载会转义 & 符号
- 属性对象上的属性重载会转义 & 符号
- addChild 方法不会转义 & 符号
- addAttribute 方法不会转义 & 符号
但这是不可能的,因为 SimpleXML 没有属性对象的概念。 addAttribute 方法是(似乎是?)添加属性的唯一方法。因此,事实证明(似乎?)SimpleXML 无法使用实体创建属性。
所有这些都揭示了 SimpleXML 的悖论。这个 API 背后的想法是提供一种与复杂事物交互的简单方式。
团队本可以添加一个 SimpleXMLAttribute 对象,但这增加了一层复杂性。如果您想要一个多对象层次结构,请使用 DomDoument。
团队本可以向 addAttribute 和 addChild 方法添加标志,但标志会使 API 更加复杂。
真正的教训在这里?也许就是这么简单就很难,而在最后期限内简单就更难了。我不知道是不是这样,但是对于 SimpleXML,似乎有人从一个简单的想法开始(使用属性重载使 XML 文档的创建变得容易),然后随着问题/功能请求的出现进行调整.
实际上,我认为这里真正的教训是只使用 JSON ;)