SimpleXMLElement 和 SimpleXMLElement::children() 是一回事吗?
Are SimpleXMLElement and SimpleXMLElement::children() the same thing?
考虑以下代码:
<?php
$foo = new SimpleXmlElement(
'<foo>
<bar>
<baz id="b1"/>
<baz id="b2"/>
<baz id="b3"/>
</bar>
</foo>
');
echo "<pre>";print_r($foo);echo "</pre><br/>";
echo "<pre>";print_r($foo->children());echo "</pre><br/>";
echo "foo===foo->children():".($foo===$foo->children()?"true":"false")."<br/>";//false
echo "foo==foo->children():".($foo==$foo->children()?"true":"false");//true
print_r 显示 foo 和 foo->children() 的相同内容。 $foo==$foo->children() 为真但 $foo===$foo->children() 为假。 $foo->children() 到底是什么?
official document有个注释可能与这个问题有关,但我无法理解它的确切含义。
Note: SimpleXML has made a rule of adding iterative properties to most
methods. They cannot be viewed using var_dump() or anything else which
can examine objects.
顾名思义,SimpleXMLElement::children 是一个成员函数,只是 returns 子元素作为来自 SimpleXMLElement class 对象的对象。
它总是 return 一个 'SimpleXMLElement' class 对象,除非节点代表一个属性(id,class 等可以被认为是属性),在这种情况下 null 是 returned.
考虑这个例子
$foo = new SimpleXmlElement(
'<foo>
<bar>
<baz id="b1">b1</baz>
<baz id="b2">b2</baz>
<baz id="b3">b3</baz>
<pas id="p1">p1</pas>
</bar>
</foo>');
$mainfoo = json_encode($foo); var_dump($mainfoo); // string(50) "{"bar":{"baz":["b1","b2","b3"],"pas":["p1","p2"]}}"
$children = json_encode($foo->children()); var_dump($children ); // string(50) "{"bar":{"baz":["b1","b2","b3"],"pas":["p1","p2"]}}"
$childrenofbar = json_encode($foo->bar->children()); var_dump($childrenofbar ); //string(42) "{"baz":["b1","b2","b3"],"pas":["p1","p2"]}"
$children_bar_pas = json_encode($foo->bar->pas); var_dump($children_bar_pas); //string(45) "{"@attributes":{"id":"p1"},"0":"p1","1":"p2"}"
我们不能使用var_dump查看和验证SimpleXmlElement 对象。所以为了方便起见,我们可以简单地 json_encode 它们和 var_dump 它们 ;)
此处第一条语句将 xml/markup 字符串转换为 SimpleXmlElement class 对象。
$foo->children() 将子元素作为 SimpleXmlElement class 对象
$foo->bar->children() 带来 'bar'.
的子元素
根据文档,SimpleXmlElement 的对象可以使用 php 循环(例如 for/foreach 等)进行迭代。
foreach($foo as $f1) {
var_dump(json_encode($f1)); // "{"baz":["b1","b2","b3"],"pas":["p1","p2"]}"
}
foreach($foo->children() as $f2) {
var_dump(json_encode($f2)); // string(42) "{"baz":["b1","b2","b3"],"pas":["p1","p2"]}"
}
children() 方法也可用于访问具有有效命名空间的标记的子元素。请参阅 documentation!
中的示例 #2
尽管名称如此,SimpleXMLElement
class 的实例可以代表一些不同的事物:
- 单个 XML 元素;在您的示例中,
$foo
表示 XML 文档 根目录中的 <foo>
元素
- XML 个同名元素的集合;例如,
$foo->bar
为您提供一个对象,其中包含所有名为 bar
的子元素
- 具有不同名称但相同父级的XML个元素的集合;这就是
->children()
给你的
- 单个XML 属性;
$foo->bar[0]->baz[0]['id']
将为您的示例中第一个 baz
的 id
属性提供一个对象
- 同一元素上 XML 个属性的集合;这就是
->attributes()
给你的
很多时候,您实际上并没有注意到自己拥有哪些,因为各种 short-hands 让您可以互换对待它们;例如:
- 属性、方法和对元素和属性集合的属性调用通常引用集合中的第一个元素。所以
$foo->bar->baz['id']
与 $foo->bar[0]->baz[0]['id']
相同
- 相反,将
foreach
循环与表示单个节点的对象一起使用会自动遍历该元素的子元素,就好像您调用了 ->children()
然而,有时您需要区分。例如,foreach ( $foo->bar as $item )
将遍历所有名为 bar
的元素;但是 foreach ( $foo->bar->children() as $item )
将访问名为 bar
的 first 元素,并遍历 它的 个子元素。
children()
方法也用于命名空间之间的切换,见
考虑以下代码:
<?php
$foo = new SimpleXmlElement(
'<foo>
<bar>
<baz id="b1"/>
<baz id="b2"/>
<baz id="b3"/>
</bar>
</foo>
');
echo "<pre>";print_r($foo);echo "</pre><br/>";
echo "<pre>";print_r($foo->children());echo "</pre><br/>";
echo "foo===foo->children():".($foo===$foo->children()?"true":"false")."<br/>";//false
echo "foo==foo->children():".($foo==$foo->children()?"true":"false");//true
print_r 显示 foo 和 foo->children() 的相同内容。 $foo==$foo->children() 为真但 $foo===$foo->children() 为假。 $foo->children() 到底是什么?
official document有个注释可能与这个问题有关,但我无法理解它的确切含义。
Note: SimpleXML has made a rule of adding iterative properties to most methods. They cannot be viewed using var_dump() or anything else which can examine objects.
顾名思义,SimpleXMLElement::children 是一个成员函数,只是 returns 子元素作为来自 SimpleXMLElement class 对象的对象。 它总是 return 一个 'SimpleXMLElement' class 对象,除非节点代表一个属性(id,class 等可以被认为是属性),在这种情况下 null 是 returned.
考虑这个例子
$foo = new SimpleXmlElement(
'<foo>
<bar>
<baz id="b1">b1</baz>
<baz id="b2">b2</baz>
<baz id="b3">b3</baz>
<pas id="p1">p1</pas>
</bar>
</foo>');
$mainfoo = json_encode($foo); var_dump($mainfoo); // string(50) "{"bar":{"baz":["b1","b2","b3"],"pas":["p1","p2"]}}"
$children = json_encode($foo->children()); var_dump($children ); // string(50) "{"bar":{"baz":["b1","b2","b3"],"pas":["p1","p2"]}}"
$childrenofbar = json_encode($foo->bar->children()); var_dump($childrenofbar ); //string(42) "{"baz":["b1","b2","b3"],"pas":["p1","p2"]}"
$children_bar_pas = json_encode($foo->bar->pas); var_dump($children_bar_pas); //string(45) "{"@attributes":{"id":"p1"},"0":"p1","1":"p2"}"
我们不能使用var_dump查看和验证SimpleXmlElement 对象。所以为了方便起见,我们可以简单地 json_encode 它们和 var_dump 它们 ;)
此处第一条语句将 xml/markup 字符串转换为 SimpleXmlElement class 对象。
$foo->children() 将子元素作为 SimpleXmlElement class 对象
$foo->bar->children() 带来 'bar'.
的子元素根据文档,SimpleXmlElement 的对象可以使用 php 循环(例如 for/foreach 等)进行迭代。
foreach($foo as $f1) {
var_dump(json_encode($f1)); // "{"baz":["b1","b2","b3"],"pas":["p1","p2"]}"
}
foreach($foo->children() as $f2) {
var_dump(json_encode($f2)); // string(42) "{"baz":["b1","b2","b3"],"pas":["p1","p2"]}"
}
children() 方法也可用于访问具有有效命名空间的标记的子元素。请参阅 documentation!
中的示例 #2尽管名称如此,SimpleXMLElement
class 的实例可以代表一些不同的事物:
- 单个 XML 元素;在您的示例中,
$foo
表示 XML 文档 根目录中的 - XML 个同名元素的集合;例如,
$foo->bar
为您提供一个对象,其中包含所有名为bar
的子元素
- 具有不同名称但相同父级的XML个元素的集合;这就是
->children()
给你的 - 单个XML 属性;
$foo->bar[0]->baz[0]['id']
将为您的示例中第一个baz
的id
属性提供一个对象 - 同一元素上 XML 个属性的集合;这就是
->attributes()
给你的
<foo>
元素
很多时候,您实际上并没有注意到自己拥有哪些,因为各种 short-hands 让您可以互换对待它们;例如:
- 属性、方法和对元素和属性集合的属性调用通常引用集合中的第一个元素。所以
$foo->bar->baz['id']
与$foo->bar[0]->baz[0]['id']
相同
- 相反,将
foreach
循环与表示单个节点的对象一起使用会自动遍历该元素的子元素,就好像您调用了->children()
然而,有时您需要区分。例如,foreach ( $foo->bar as $item )
将遍历所有名为 bar
的元素;但是 foreach ( $foo->bar->children() as $item )
将访问名为 bar
的 first 元素,并遍历 它的 个子元素。
children()
方法也用于命名空间之间的切换,见