PHP
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

SimpleXMLElement::__construct> <SimpleXMLElement::attributes
Last updated: Fri, 03 Jul 2009

view this page in

SimpleXMLElement::children

(PHP 5 >= 5.0.1)

SimpleXMLElement::children指定したノードの子ノードを見付ける

説明

SimpleXMLElement
SimpleXMLElement children ([ string $ns [, bool $is_prefix ]] )

このメソッドは、指定した要素のメンバーである子を見つけます。 結果は、通常の反復子により取得できます。

注意: SimpleXML では、ほとんどのメソッドに反復処理を追加するための手順が定義されています。 これらは、var_dump() やオブジェクトを評価する他の手段で 見ることはできません。

パラメータ

ns

is_prefix

デフォルトは FALSE

返り値

変更履歴

バージョン 説明
5.2.0 オプションのパラメータ is_prefix が追加されました。

例1 children() 疑似配列を走査する

<?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 person begot a son who begot a daughter; The person
begot a daughter who begot a son; and that son begot a son



add a note add a note User Contributed Notes
SimpleXMLElement::children
rodmen at gmail dot com
22-May-2009 12:32
Transform xml to array php

<?php
function xml2phpArray($xml,$arr){
   
$iter = 0;
        foreach(
$xml->children() as $b){
               
$a = $b->getName();
                if(!
$b->children()){
                       
$arr[$a] = trim($b[0]);
                }
                else{
                       
$arr[$a][$iter] = array();
                       
$arr[$a][$iter] = xml2phpArray($b,$arr[$a][$iter]);
                }
       
$iter++;
        }
        return
$arr;
}

$Array = simplexml_load_string(file_get_contents('myfile.xml'));
print_r(xml2phpArray($Array,array()));
?>
G dot B dot Yahav at Gmail dot com
26-Mar-2009 03:26
I done a very nice function to run over the XML element recursivly with SimpleXML, and print it on the screen

here it is:

<?php

$xml_han
= new SimpleXMLElement( "data.xml", null, true );

print
RecursiveXML( $xml_han );
function
RecursiveXML( SimpleXMLElement $han, $preffix = "")
{
    if(
count( $han->children() ) < 1 )
    {
        return
$preffix . "&lt;" . $han->getName() . warpAttributes( $han->attributes() ) . "&gt;&nbsp;" . $han . "&nbsp;&lt;/" . $han->getName() . "&gt;<br />";
    }
   
   
$ret = $preffix . "&lt;" . $han->getName() . warpAttributes( $han->attributes() ) . "&gt;<br />";
    foreach(
$han->children() as $key => $child )
    {
       
$ret .= RecursiveXML($child , $preffix . "|--&nbsp;&nbsp;&nbsp;" );
    }
    return
$ret;
}

?>

enjoy :)
hoseinnj at google&#39;s great mail dot com
20-Mar-2009 04:25
Quick easy way to turn objectified SimpleXMLElement data into an array.

<?php
function get_xml_from_some_source(){
//blah blah blah build cUrl
$data = @curl_exec($ch);
$newdata = new SimpleXMLElement($data);
$new = xml2array_parse($newdata);
}

function
xml2array_parse($xml){
     foreach (
$xml->children() as $parent => $child){
        
$return["$parent"] = xml2array_parse($child)?xml2array_parse($child):"$child";
     }
     return
$return;
 }
?>

My first post, be nice.  ;-)
adamjones at hotmail dot com
18-Mar-2009 03:31
If the object has no children, I believe it throws this exception:

    PHP Fatal error:  Call to a member function children() on a non-object

There is no way to check if it has children before calling this.
TSidoti
11-Mar-2009 09:47
If you run into a tag that has both text and tags in it like lars dot a dot johansson, the best way to about about using that tag is to import it into dom using dom_import_simplexml().  According to http://devzone.zend.com/node/view/id/688 , simpleXML simply does not handle cases like this and will return only the tags. 

"The second solution is to bypass SimpleXML for certain portions of your document. One of the explicit design goals of PHP5's XML support was to allow all extensions to interoperate at a minimal cost. Since LibXML2 is the lingua franca of all XML extensions, DOM and SimpleXML objects can be exchanged with zero copies. It's just a different way of viewing the same underlying object! By this method, the DOM extension can "import" SimpleXML objects and use them as DOM objects, and vice versa. When you need to use a DOM feature you can, and when you need SimpleXML's ease of processing, you have that too."

The other option in the article is to use the asXML() method and than parse the information from there.
Anonymous
06-Sep-2008 09:39
for XML namespaces such as <dc:creator> in RSS feeds use

<?php
    $xml
= new SimpleXMLElement($string);
   
$item = $xml->channel[0]->item[0];
   
$dc = $item->children("http://purl.org/dc/elements/1.1/");
    echo
$dc->creator;
?>
transglobe at gmx dot de
20-Mar-2008 07:37
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...)
crescentfreshpot at yahoo dot com
11-Dec-2007 01:16
Just a warning that the iterable returned from children() contains the '@attributes' key, which is "invisible" during a foreach but can be seen if using a different construct, such as list()=each() or casting to an array before iterating w/ foreach.
lars dot a dot johansson at se dot atlascopco dot com
21-Nov-2007 03:41
Hi,
Anyone who can tell me how to parse an xml tag that contains both text and childs. e.g.
...<sql>select * from table;<conv>default.php</conv><sql>...

The only way I could extract the text (select...) was with the following snippet

foreach($xml->children() as $k => $v ) {
$elem = count($v);
$xmla = (array) $xml[0];
if (is_string($xmla["$k"]) and $elem) {
    // $xmla["$k"] is 'select * from table'
}
...}
which is not very pretty.
Convert the child xml object to an array and check if the child is a string and not an end node. It's un ugly hack, but it does the job.
aero
24-May-2007 12:35
Here's a slightly modified function that transforms xml data into an associative array with the indices's into the array have the following syntax, parent.child etc.

So for

<meal>
   <type>Lunch</type>
   <time>12:30</time>
   <menu>
     <entree>salad</entree>
     <maincourse>steak</maincourse>
   </menu>
</meal>

The array would look like this...

array(4) {
  ["type"]=>
  string(5) "Lunch"
  ["time"]=>
  string(5) "12:30"
  ["menu.entree"]=>
  string(5) "salad"
  ["menu.maincourse"]=>
  string(5) "steak"
}

Here's an example

<?php

$xml
= new SimpleXMLElement(
'<meal>
   <type>Lunch</type>
   <time>12:30</time>
   <menu>
     <entree>salad</entree>
     <maincourse>steak</maincourse>
   </menu>
</meal>'
);

$vals = array();
RecurseXML($xml,$vals);

foreach(
$vals as $key=>$value)
  print(
"{$key} = {$value}<BR>\n");

function
RecurseXML($xml,&$vals,$parent="")
{
  
$child_count = 0;
   foreach(
$xml as $key=>$value)
   {
     
$child_count++;    
     
$k = ($parent == "") ? (string)$key : $parent . "." . (string)$key;
      if(
RecurseXML($value,$vals,$k) == 0// no childern, aka "leaf node"
        
$vals[$k] = (string)$value;  
   }
   return
$child_count;
}

The output:

type = Lunch
time
= 12:30
menu
.entree = salad
menu
.maincourse = steak

?>
aero
24-May-2007 12:07
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
taylorbarstow at that google mail thingy
21-Apr-2006 11:38
Sometimes you actually want an array, not a pseudo array.   This is especially true when you aren't dealing with attributes (i.e., you just want the array of child nodes).

Do like this:

<?php
$children
= $sxml->xpath('child::node()');
?>

The reason you might want this is to be able to use array functions like array_shift, array_pop, etc.  This is especially true when you are writing recursive functions.  Simplexml works really well in iterative programming, but if you try to implement recursion it gets ugly.
Sebastian
27-Oct-2005 07:45
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.
no-one
01-Jun-2005 10:05
For anyone who hasn't read Sterling Hughe's article (http://www.zend.com/php5/articles/php5-simplexml.php):

<?php
$xml_document
=<<<EOT
<?xml version="1.0"?>
<root xmlns:foo="http://google.com">
  <foo:bar>baz</foo:bar>
</root>
EOT;

$xml_document = simplexml_load_xml($xml_document);

$foo_ns_bar = $xml_document->children('http://google.ca');

echo
$foo_ns_bar->bar[0]; // prints 'baz'
?>
Andrew Rose (rose dot andrew at gmail dot com)
16-Mar-2005 09:48
The example below shows the basic use of depth-first recursion to span the xml tree.

This is coded for the command line, and it prints out the original sentance above and then the copy cat sentence it creates itself for comparison, which as you will see; this example is slightly off from, I'll leave it upto you to resolve this issue.

All in all I personaly think xml and recursion go hand in hand, so if you don't understand recursion but know xml and want to use php to manipulate xml you will need to learn about recursion at some point.

<?
$xml
= simplexml_load_string(
'<person>
 <child role="son">
  <child role="daughter"/>
 </child>
 <child role="daughter">
  <child role="son">
   <child role="son"/>
  </child>
 </child>
</person>'
);

function
recurse($child)
 {
   foreach(
$child->children() as $children) {
     echo
' who begot a '.$children['role'];
    
recurse($children);
   }
    return;
 }

foreach(
$xml->children() as $children) {
 echo
'The person begot a '.$children['role'];
 
recurse($children, 0);
 echo
'; ';
}

echo
"\n";
echo
'The person begot a son who begot a daughter; The person begot a daughter who begot a son; and that son begot a son'."\n";

?>
zyxwvu at users dot sourceforge dot net
16-Feb-2004 03:32
File:

<category>
  <item>text</item>
  <bold>text</bold>
  <item>text</item>
  <item>text</item>
  <mark>text</mark>
  <bold>text</bold>
</category>

If you want to get also names of the tags, you can use this loop layout:

foreach($category -> children() as $name => $node){
  echo $name.'<br/>';
}

 
show source | credits | stats | sitemap | contact | advertising | mirror sites