当前位置: 首页 > 知识库问答 >
问题:

SimpleXML子级属性在有命名空间和没有命名空间时的行为不同

干旺
2023-03-14

SimpleXML示例页的"示例#5使用属性"部分指出:

访问元素的属性,就像访问数组的元素一样。

在SimpleXMLElement中的示例#1::cHilrey()使用$元素['属性']语法来访问子属性;

将命名空间添加到该代码,将禁用对属性的访问:

$xml = new SimpleXMLElement(
'<person xmlns:a="foo:bar">
  <a:child role="son">
    <a:child role="daughter"/>
  </a:child>
  <a:child role="daughter">
    <a:child role="son">
      <a:child role="son"/>
    </a:child>
  </a:child>
</person>');
foreach ($xml->children('a', true) as $second_gen) {
    echo ' The person begot a ' . $second_gen['role'];
    foreach ($second_gen->children('a', true) as $third_gen) {
        echo ' who begot a ' . $third_gen['role'] . ';';
        foreach ($third_gen->children('a', true) as $fourth_gen) {
            echo ' and that ' . $third_gen['role'] . ' begot a ' . $fourth_gen['role'];
        }
    }
}
// results
// The person begot a who begot a ; The person begot a who begot a ; and that begot a 
// expected
// The person begot a son who begot a daughter; The person begot a daughter who begot a son; and that son begot a son

这里有很多问题指向同一个解决方案,即使用simplexmlement::attributes()函数而不是作为数组进行访问,但没有一个答案解释原因。

使用名称空间时的这种不同行为是错误吗?文件是否过时?我们是否应该始终使用simplexmlement::attributes(),并避免使用推荐的类似数组的语法?

注意:我使用的是PHP5.5.9-1ubuntu4.9

  • 正在检索命名空间子级的属性

共有1个答案

阎修杰
2023-03-14

其原因实际上与SimpleXML无关,而是与标准中关于XML名称空间工作方式的一些令人惊讶的细节有关。

在您的示例中,您使用前缀a声明了一个名称空间,因此要声明某个属性位于该名称空间中,您必须使用a:作为其名称的前缀,就像使用元素一样:

<a:child a:role="daughter"/>

似乎有一种常见的假设,即没有名称空间前缀的属性与它所在的元素位于同一名称空间中,但事实并非如此。上述示例与您的示例不同:

<a:child role="daughter"/>

您可能会看到的另一种情况是,默认(未固定)命名空间中存在:

<person xmlns="http://example.com/foo.bar"><child role="daughter" /></person>

这里,元素位于http://example.com/foo.bar名称空间,但角色属性仍然不可用!正如在这个相关问题中所讨论的,XML名称空间规范的相关部分包括以下语句:

无前缀属性名称的命名空间名称始终没有值。

也就是说,没有命名空间前缀的属性永远不会出现在任何命名空间中,不管文档的其余部分是什么样子。

那么,这对SimpleXML有什么影响呢?

SimpleXML的工作原理是在使用-

所以当你写作时:

$children = $xml->children('a', true);

或:

$children = $xml->children('http://example.com/foo.bar');

“当前名称空间”是foo:bar-

当你随后写道:

$attributes = $children->attributes();

这与以下解释相同:

$attributes = $children->attributes(null);

所以现在,"当前命名空间"是null。现在,当您寻找没有命名空间的属性时,您会找到它们。

 类似资料:
  • 问题内容: 我正在尝试为RSS提要中的每个条目获取entry-> id和entry-> cap:parameter-> value…。以下是我正在使用的代码。它正确显示了ID,但未显示值字段。…请帮助。 我在这里先向您的帮助表示感谢。 问题答案: 该元素是不是在同一个命名空间为: 因此,您必须再次致电。 代码(演示)

  • 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变化。 “内部模块”现在称做“命名空间”。 “外部模块”现在则简称为“模块”,这是为了与ECMAScript 2015里的术语保持一致,(也就是说 module X { 相当于现在推荐的写法 namespace X {)。 这篇文章描述了如何在TypeScript里使用命名空间(之前叫做“内部模块”)来组织你的代码

  • Let the word of Christ dwell in you richly in all wisdom; teaching and admonishing one another in psalms and hymns and spiritual songs, singing with grrace in your hearts tto the Lord. And whatsoever

  • 客户端有许多“命名空间”,通常是一些公开的可管理功能。命名空间对应 Elasticsearch 中各种可管理的 endpoint。下面是全部的命名空间: **命名空间** **功能** `indices()` 索引数据统计和显示索引信息 `nodes()` 节点数据统计和显示节点信息 `cluster()` 集群数据统计和显示集群信息 `snapshot()` 对集群和索引进行拍摄快照或恢复数据

  • 命名空间 由于 js 环境极少命名空间管理模块, namespace 相对陌生, 比如有这样的文件结构, src/ demo/ core.cljs 可以看到 core.cljs 的路径就是: src/demo/core.cljs 注意 JVM 环境有个 classpath 的环境变量, 用于判断怎样查找源码, classpath 对应多个路径, 也可能是 jar 包, 而 jar 包中

  • 命名空间,英文名字:namespaces 在研习命名空间以前,请打开在python的交互模式下,输入:import this >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than