SimpleXMLElement::children
(PHP 5 >= 5.0.1)
SimpleXMLElement::children — Finds children of given node
Description
This method finds the children of an element. The result follows normal iteration rules.
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.
Parameters
-
ns
-
An XML namespace.
-
is_prefix
-
If
is_prefix
isTRUE
,ns
will be regarded as a prefix. IfFALSE
,ns
will be regarded as a namespace URL.
Return Values
Returns a SimpleXMLElement element, whether the node has children or not.
Changelog
Version | Description |
---|---|
5.2.0 |
The optional parameter is_prefix was added.
|
Examples
Example #1 Traversing a children() pseudo-array
<?php
$xml = new SimpleXMLElement(
'<person>
<child role="son">
<child role="daughter"/>
</child>
<child role="daughter">
<child role="son">
<child role="son"/>
</child>
</child>
</person>');
foreach ($xml->children() as $second_gen) {
echo ' The person begot a ' . $second_gen['role'];
foreach ($second_gen->children() as $third_gen) {
echo ' who begot a ' . $third_gen['role'] . ';';
foreach ($third_gen->children() as $fourth_gen) {
echo ' and that ' . $third_gen['role'] .
' begot a ' . $fourth_gen['role'];
}
}
}
?>
The above example will output:
The person begot a son who begot a daughter; The person begot a daughter who begot a son; and that son begot a son
Example #2 Using namespaces
<?php
$xml = '<example xmlns:foo="my.foo.urn">
<foo:a>Apple</foo:a>
<foo:b>Banana</foo:b>
<c>Cherry</c>
</example>';
$sxe = new SimpleXMLElement($xml);
$kids = $sxe->children('foo');
var_dump(count($kids));
$kids = $sxe->children('foo', TRUE);
var_dump(count($kids));
$kids = $sxe->children('my.foo.urn');
var_dump(count($kids));
$kids = $sxe->children('my.foo.urn', TRUE);
var_dump(count($kids));
$kids = $sxe->children();
var_dump(count($kids));
?>
int(0) int(2) int(2) int(0) int(1)
Notes
SimpleXMLElement::children() returns a node object no matter if the current node has children or not. Use count() on the return value to see if there are any children. As of PHP 5.3.0, SimpleXMLElement::count() may be used instead.
See Also
- SimpleXMLElement::count() - Counts the children of an element
- count() - Count all elements in an array, or something in an object
- Функция SimpleXMLElement::addAttribute() - Добавляет атрибут к SimpleXML-элементу
- Функция SimpleXMLElement::addChild() - Добавляет дочерний элемент к узлу XML
- Функция SimpleXMLElement::asXML() - Возвращает сформированный XML документ в виде строки используя SimpleXML элемент
- Функция SimpleXMLElement::attributes() - Возвращает атрибуты элемента
- Функция SimpleXMLElement::children() - Поиск дочерних элементов данного узла
- Функция SimpleXMLElement::__construct() - Создание нового SimpleXMLElement объекта
- Функция SimpleXMLElement::count() - Считает количество дочерних элементов у текущего элемента
- Функция SimpleXMLElement::getDocNamespaces() - Возвращает объявленное пространство имен в документе
- Функция SimpleXMLElement::getName() - Получение имени XML элемента
- Функция SimpleXMLElement::getNamespaces() - Получение пространств имен, используемых в документе
- Функция SimpleXMLElement::registerXPathNamespace() - Создает префикс/пространство имен контекста для следующего XPath запроса
- Функция SimpleXMLElement::saveXML() - Псевдоним SimpleXMLElement::asXML
- Функция SimpleXMLElement::__toString() - Returns the string content
- Функция SimpleXMLElement::xpath() - Запускает XPath запрос к XML данным
Коментарии
Just a quick addition:
If you need to access a child node which contains a dash, you need to encapsulate it with {""}.
For example:
<?php
foreach ($domain->domain-listing as $product) {
}
?>
The example above doesn't work because of the dash. But instead you need to use:
<?php
foreach ($domain->{"domain-listing"} as $product) {
}
?>
At least for me the second example works perfectly fine.
Here's a simple, recursive, function to transform XML data into pseudo E4X syntax ie. root.child.value = foobar
<?php
error_reporting(E_ALL);
$xml = new SimpleXMLElement(
'<Patriarch>
<name>Bill</name>
<wife>
<name>Vi</name>
</wife>
<son>
<name>Bill</name>
</son>
<daughter>
<name>Jeri</name>
<husband>
<name>Mark</name>
</husband>
<son>
<name>Greg</name>
</son>
<son>
<name>Tim</name>
</son>
<son>
<name>Mark</name>
</son>
<son>
<name>Josh</name>
<wife>
<name>Kristine</name>
</wife>
<son>
<name>Blake</name>
</son>
<daughter>
<name>Liah</name>
</daughter>
</son>
</daughter>
</Patriarch>');
RecurseXML($xml);
function RecurseXML($xml,$parent="")
{
$child_count = 0;
foreach($xml as $key=>$value)
{
$child_count++;
if(RecurseXML($value,$parent.".".$key) == 0) // no childern, aka "leaf node"
{
print($parent . "." . (string)$key . " = " . (string)$value . "<BR>\n");
}
}
return $child_count;
}
?>
The output....
.name = Bill
.wife.name = Vi
.son.name = Bill
.daughter.name = Jeri
.daughter.husband.name = Mark
.daughter.son.name = Greg
.daughter.son.name = Tim
.daughter.son.name = Mark
.daughter.son.name = Josh
.daughter.son.wife.name = Kristine
.daughter.son.son.name = Blake
.daughter.son.daughter.name = Liah
I made a slightly differnt approch towards the RecurseXML function. Beeing hungry I had problems with the code, as it did just overwrite two <maincourse>s. So here is what I did:
<?php
$xml = new SimpleXMLElement(
'<meal>
<type>Lunch</type>
<time>12:30</time>
<menu>
<entree>salad</entree>
<maincourse>
<part>ships</part>
<part>steak</part>
</maincourse>
<maincourse>
<part>fisch</part>
<part>rice</part>
</maincourse>
<maincourse>
<part>wine</part>
<part>cheese</part>
</maincourse>
</menu>
</meal>');
$vals = array();
RecurseXML($xml,$vals);
foreach($vals as $key=>$value)
print("{$key} = {$value}<BR>\n");
function RecurseXML($xml,&$vals,$parent="") {
$childs=0;
$child_count=-1; # Not realy needed.
$arr=array();
foreach ($xml->children() as $key=>$value) {
if (in_array($key,$arr)) {
$child_count++;
} else {
$child_count=0;
}
$arr[]=$key;
$k=($parent == "") ? "$key.$child_count" : "$parent.$key.$child_count";
$childs=RecurseXML($value,$vals,$k);
if ($childs==0) {
$vals[$k]= (string)$value;
}
}
return $childs;
}
?>
Output is like this:
type.0 = Lunch
time.0 = 12:30
menu.0.entree.0 = salad
menu.0.maincourse.0.part.0 = ships
menu.0.maincourse.0.part.1 = steak
menu.0.maincourse.0 =
menu.0.maincourse.1.part.0 = fisch
menu.0.maincourse.1.part.1 = rice
menu.0.maincourse.1 =
menu.0.maincourse.2.part.0 = wine
menu.0.maincourse.2.part.1 = cheese
menu.0.maincourse.2 =
menu.0 =
(Not beautiful, but it solved my case...)
SimpleXMLElement::children can return null in this case:
<?php
$xml = '
<root attr="Hello"/>
';
$sxe = new SimpleXMLElement($xml);
$sxe_xpath = $sxe->xpath('/root/@attr')[0];
$children = $sxe_xpath->children();
var_export($children); // Is null
?>