Php SimpleXML儿童';s属性在有命名空间和没有命名空间时的行为不同

Php SimpleXML儿童';s属性在有命名空间和没有命名空间时的行为不同,php,xml,simplexml,Php,Xml,Simplexml,“示例#5使用属性”一节说明: 访问元素的属性,就像访问数组的元素一样 示例#1使用$element['attribute']语法访问儿童属性 向该代码添加命名空间将禁用对属性的访问: $xml = new SimpleXMLElement( '<person xmlns:a="foo:bar"> <a:child role="son"> <a:child role="daughter"/>

“示例#5使用属性”一节说明:

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

示例#1使用
$element['attribute']
语法访问儿童属性

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

$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
$xml=新的SimpleXMLElement(
'


  • 根据标准,这实际上与SimpleXML无关,而是与XML名称空间如何工作的一些令人惊讶的细节有关

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

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

    “当前名称空间”是
    foo:bar
    。随后使用
    ->childElement
    ['attribute']
    语法将在该名称空间中查找-您不需要每次都再次调用
    children()
    ,但在那里将找不到未固定的属性,因为它们没有名称空间

    当你随后写道:

    $attributes = $children->attributes();
    
    这与以下内容的解释相同:

    $attributes = $children->attributes(null);
    
    现在,“当前名称空间”是
    null
    。现在,当您查找没有名称空间的属性时,您将找到它们

    $children = $xml->children('a', true);
    
    $children = $xml->children('http://example.com/foo.bar');
    
    $attributes = $children->attributes();
    
    $attributes = $children->attributes(null);