Enjoy an ad free experience by logging in. Not a member yet?
Register .
05-20-2006, 06:13 AM
PM User |
#1
New to the CF scene
Join Date: May 2006
Location: Texas, USA
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
SimpleXML Object to Array
I work with a lot of XML and have found SimpleXML to be a great tool, but often it's easier to have it all in an array form that still maintains the order of elements. I came up with this function -- maybe someone else will find it useful, too.
PHP Code:
function convertXmlObjToArr ( $obj , & $arr )
{
$children = $obj -> children ();
foreach ( $children as $elementName => $node )
{
$nextIdx = count ( $arr );
$arr [ $nextIdx ] = array();
$arr [ $nextIdx ][ '@name' ] = strtolower ((string) $elementName );
$arr [ $nextIdx ][ '@attributes' ] = array();
$attributes = $node -> attributes ();
foreach ( $attributes as $attributeName => $attributeValue )
{
$attribName = strtolower ( trim ((string) $attributeName ));
$attribVal = trim ((string) $attributeValue );
$arr [ $nextIdx ][ '@attributes' ][ $attribName ] = $attribVal ;
}
$text = (string) $node ;
$text = trim ( $text );
if ( strlen ( $text ) > 0 )
{
$arr [ $nextIdx ][ '@text' ] = $text ;
}
$arr [ $nextIdx ][ '@children' ] = array();
convertXmlObjToArr ( $node , $arr [ $nextIdx ][ '@children' ]);
}
return;
}
If you have the following XML:
Code:
<books>
<novel author="John Doe"><title>John's Novel</title></novel>
</books>
You'll get an array similar to:
Code:
Array
(
@name => books
@attributes => array ( )
@children => array
(
array
(
@name => novel
@attributes => array ( author => John Doe )
@children => array
(
array ( @name => title, @attributes => array ( ), @text => John's Novel )
)
)
)
)
05-01-2008, 11:38 PM
PM User |
#2
New to the CF scene
Join Date: May 2008
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
can you you give further example?
Hi, can you demonstrate further example, e.g.
a) how do you call the function, do you add arguments to the function?
b) what coding syntax do you use to retrieve the array information.
Thanks ~ James
05-02-2008, 12:09 AM
PM User |
#3
New to the CF scene
Join Date: May 2006
Location: Texas, USA
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
OK... say I have XML like this stored in a file called "books.xml":
Code:
<books>
<novel author="John Doe"><title>John's Novel</title></novel>
<novel author="Jane Doe"><title>Jane's Novel</title></novel>
<novel author="Jack Doe"><title>Jack's Novel</title></novel>
</books>
In my PHP code:
PHP Code:
$xmlObject = simplexml_load_file ( 'books.xml' );
$xmlArr = array();
convertXmlObjToArr ( $xmlObject , $xmlArr );
foreach ( $xmlArr as $arr )
{
// outer array is always base element, in this case, books... we need the children
if (isset( $arr [ '@children' ]) && is_array ( $arr [ '@children' ]))
{
foreach ( $arr [ '@children' ] as $novel )
{
// the title is actually a child element of novel
echo 'Title: ' . $novel [ '@children' ][ 0 ][ '@text' ] . '<br />' ;
// author is an attribute of the novel tag
echo 'Author: ' . $novel [ '@attributes' ][ 'author' ] . '<br /><br />' ;
}
}
}
I hope this helps.
08-22-2008, 11:02 AM
PM User |
#4
New to the CF scene
Join Date: Aug 2008
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Hi There !
I also have a problem with simpleXML , I have to make text of an XML file editable, so I parse XML file with attributes() and children() method to build an HTML form.
the problem is to get data back to xml to regenerate xml file
i have the data in an array with post method
Code:
[obj] => Array
(
[content] => Array
(
[@attributes] => Array
(
[center_title] => test
)
)
...
it is exactly the same that simpleXML object excepts it s an array and not an object
dont know actually how i gonna get the job done
any ideas ?
08-22-2008, 12:55 PM
PM User |
#5
New to the CF scene
Join Date: May 2006
Location: Texas, USA
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Honestly, I only use this to quickly read in complex XML files (like RSS/ATOM feeds). If I need to manipulate XML and write it back out to the browser or a file, then I will typically use DOM or XMLWriter. You should check them out in the PHP manual as they'll probably suit your needs better.
07-18-2009, 11:15 PM
PM User |
#6
New to the CF scene
Join Date: Jul 2009
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Here is my code!
It does not respect attributes but it transformes the Xml to a simpler array. Let me know if you use it or if you find some bugs :-)
Code:
function convertXmlObjToArr($obj, &$arr){
$children = $obj->children();
$executed = false;
foreach ($children as $elementName => $node){
if($arr[$elementName]!=null){
if($arr[$elementName][0]!==null){
$i = count($arr[$elementName]);
convertXmlObjToArr($node, $arr[$elementName][$i]);
}else{
$tmp = $arr[$elementName];
$arr[$elementName] = array();
$arr[$elementName][0] = $tmp;
$i = count($arr[$elementName]);
convertXmlObjToArr($node, $arr[$elementName][$i]);
}
}else{
$arr[$elementName] = array();
convertXmlObjToArr($node, $arr[$elementName]);
}
$executed = true;
}
if(!$executed&&$children->getName()==""){
$arr = (String)$obj;
}
return;
}
08-28-2009, 02:16 PM
PM User |
#7
New to the CF scene
Join Date: Aug 2009
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
The same Frederic_2008 code snippet, but without the warning on
PHP Code:
if( $arr [ $elementName ]!= null ){
in case the
PHP Code:
$arr [ $elementName ] is = NULL
PS: thanks Frederic_2008!
PHP Code:
/** * Parse a SimpleXMLElement object recursively into an Array. * Attention: attributes skipped * * * @param $xml The SimpleXMLElement object * @param $arr Target array where the values will be stored * @return NULL */ private function convertXmlObjToArr ( $obj , & $arr ) { $children = $obj -> children (); $executed = false ; foreach ( $children as $elementName => $node ) { if( array_key_exists ( $elementName , $arr ) ) { if( array_key_exists ( 0 , $arr [ $elementName ] ) ) { $i = count ( $arr [ $elementName ]); $this -> convertXmlObjToArr ( $node , $arr [ $elementName ][ $i ]); } else { $tmp = $arr [ $elementName ]; $arr [ $elementName ] = array(); $arr [ $elementName ][ 0 ] = $tmp ; $i = count ( $arr [ $elementName ]); $this -> convertXmlObjToArr ( $node , $arr [ $elementName ][ $i ]); } } else { $arr [ $elementName ] = array(); $this -> convertXmlObjToArr ( $node , $arr [ $elementName ]); } $executed = true ; } if(! $executed && $children -> getName ()== "" ) { $arr = (String) $obj ; } return ; }
09-02-2009, 04:12 PM
PM User |
#8
New to the CF scene
Join Date: Aug 2009
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
it was so buggy...
It was so buggy I had to find for another ready-made solution:
This is perfect:
http://us3.php.net/manual/en/class.s...ator.php#92323
Quote:
Originally Posted by
matteo
The same Frederic_2008 code snippet, but without the warning on
PHP Code:
if( $arr [ $elementName ]!= null ){
in case the
PHP Code:
$arr [ $elementName ] is = NULL
PS: thanks Frederic_2008!
PHP Code:
/**
* Parse a SimpleXMLElement object recursively into an Array.
* Attention: attributes skipped
*
*
* @param $xml The SimpleXMLElement object
* @param $arr Target array where the values will be stored
* @return NULL
*/
private function convertXmlObjToArr ( $obj , & $arr )
{
$children = $obj -> children ();
$executed = false ;
foreach ( $children as $elementName => $node )
{
if( array_key_exists ( $elementName , $arr ) )
{
if( array_key_exists ( 0 , $arr [ $elementName ] ) )
{
$i = count ( $arr [ $elementName ]);
$this -> convertXmlObjToArr ( $node , $arr [ $elementName ][ $i ]);
}
else
{
$tmp = $arr [ $elementName ];
$arr [ $elementName ] = array();
$arr [ $elementName ][ 0 ] = $tmp ;
$i = count ( $arr [ $elementName ]);
$this -> convertXmlObjToArr ( $node , $arr [ $elementName ][ $i ]);
}
}
else
{
$arr [ $elementName ] = array();
$this -> convertXmlObjToArr ( $node , $arr [ $elementName ]);
}
$executed = true ;
}
if(! $executed && $children -> getName ()== "" )
{
$arr = (String) $obj ;
}
return ;
}
Jump To Top of Thread
Thread Tools
Rate This Thread
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
All times are GMT +1. The time now is 11:25 AM .
Advertisement
Log in to turn off these ads.