PDA

Pogčedajte punu verziju : XML u array


bluesman
05. 11. 2005., 17:41
Da li neko ima neki lep parser za XML da ga lepo spakuje u array? Nemam trenutno vremena da ga pisem a treba mi za juce.

Ilija Studen
05. 11. 2005., 17:53
Ja sam koristio http://pear.php.net/package/XML_Tree

Ne prebacuje u array već u tree like strukturu (u situaciji objekat vs. niz uvek biram objekat ;) ), savršen kako za parsiranje tako i za generisanje XML fajlova. Meni se svideo jer jako liči na XMLDocument Delphi komponentu.

Verujem da ti treba nešto jednostavnije, ali možda ovo odradi posao. PEAR je, lako se instalira i koristi, a savršeno radi posao.

mega023
05. 11. 2005., 18:47
Ilija, moze li neki jednostavniji primer...
kako da iz XML-a dobijem stablo koriscenjem XML Tree

Ilija Studen
05. 11. 2005., 19:31
Trenutno imam jako malo primera u webrootu. XML_Tree sam koristio u PHP4 projektima, a takvih je jako malo u zadnje vreme (tačnije 1 od desetak zadnjih ;) ) tako da bih morao da kopam po arhivi da bih našao nešto korisno.

Inače, ima end user (http://pear.php.net/manual/en/package.xml.xml-tree.php) (koja je štura) i API (http://pear.php.net/package/XML_Tree/docs/latest/) dokumentacija (koja je takođe štura) na PEAR sajtu.

bluesman
05. 11. 2005., 21:40
Tipican Ilija :)

Treba mi neka obicna procedura koja ce da protrci kroz XML i napravi tree (bilo array ili objekat...) a ne 2 klase + PEAR zbog jedne simple stvari. Ako ima super, ako nema, moram sam :)

Ilija Studen
05. 11. 2005., 22:15
Pa dobro ;)

Moji su zahtevi bili nešto složeniji: trebalo mi je kako za parsiranje tako i za generisanje XML fajlova (za backup i export), plus sam imao iskustva sa sličnim APIjem (spomenuta Delphi komponenta) tako da mi je XML_Tree legao kao kec na 11.

Iskopao sam iz jednog starijeg projekta XML klasu. Meni se nije svidelo kako radi, posebno što ekstremno ružno barata sa atributima pa je na kraju nisam ni koristio (back to XML_Tree, jedna od primera gde narodna "Prečicom preče, naokolo bliže" jako fino leži).

No, radi baš ono što tebi treba... Ili bar približno.

nixa
05. 11. 2005., 23:10
evo jednu koju ja koristim :) nije nesto ali vrsi sitan posao :)


<?php
/**
* @class xml2array
*/

class xml2array
{

/**
* constructor
*/
function xml2array( $xml )
{
// check for file
if ( file_exists($xml) )
$xml = file_get_contents( $xml );

// check for string, open in dom
if ( is_string($xml) )
{
$xml = domxml_open_mem( $xml );
$this->root_element = $xml->document_element();
}

// check for dom-creation,
if ( is_object( $xml ) && $xml->node_type() == XML_DOCUMENT_NODE )
{
$this->root_element = $xml->document_element();
//$this->xml_string = $xml->dump_mem(true);
return TRUE;
}

if ( is_object( $xml ) && $xml->node_type() == XML_ELEMENT_NODE )
{
$this->root_element = $xml;
return TRUE;
}

return FALSE;
}

/**
* recursive function to walk through dom and create array
*/
function _recNode2Array( $domnode )
{
if ( $domnode->node_type() == XML_ELEMENT_NODE )
{

$childs = $domnode->child_nodes();
foreach($childs as $child)
{
if ($child->node_type() == XML_ELEMENT_NODE)
{
$subnode = false;
$prefix = ( $child->prefix() ) ? $child->prefix().':' : '';

// try to check for multisubnodes
foreach ($childs as $testnode)
if ( is_object($testnode) )
if ($child->node_name() == $testnode->node_name() && $child != $testnode)
$subnode = true;

if ( is_array($result[ $prefix.$child->node_name() ]) )
$subnode = true;

if ($subnode == true)
$result[ $prefix.$child->node_name() ][] = $this->_recNode2Array($child);
else
$result[ $prefix.$child->node_name() ] = $this->_recNode2Array($child);
}
}

if ( !is_array($result) ){
// correct encoding from utf-8 to locale
// NEEDS to be updated to correct in both ways!
$result['#text'] = html_entity_decode(htmlentities($domnode->get_content(), ENT_COMPAT, 'UTF-8'), ENT_COMPAT,'ISO-8859-15');
}

if ( $domnode->has_attributes() )
foreach ( $domnode->attributes() as $attrib )
{
$prefix = ( $attrib->prefix() ) ? $attrib->prefix().':' : '';
$result["@".$prefix.$attrib->name()] = $attrib->value();
}

return $result;
}
}

/**
* caller func to get an array out of dom
*/
function getResult()
{
if ( $resultDomNode = $this->root_element )
{
$array_result[ $resultDomNode->tagname() ] = $this->_recNode2Array( $resultDomNode );
return $array_result;
} else
return false;
}

function getEncoding()
{
preg_match("~\<\?xml.*encoding=[\"\'](.*)[\"\'].*\?\>~i",$this->xml_string,$matches);
return ($matches[1])?$matches[1]:"";
}

function getNamespaces()
{
preg_match_all("~[[:space:]]xmlns:([[:alnum:]]*)=[\"\'](.*?)[\"\']~i",$this->xml_string,$matches,PREG_SET_ORDER);
foreach( $matches as $match )
$result[ $match[1] ] = $match[2];
return $result;
}
}
?>



mada pokusaj sa codewalkersa ovu
http://codewalkers.com/seecode/185.html

mega023
05. 11. 2005., 23:33
hm...
dobijam ovaj error

Fatal error: Call to undefined function: domxml_open_mem() in /home/user/public_html/search5.php on line 16

Ilija Studen
06. 11. 2005., 00:17
Kod koji je nixa postovao zateva DOM XML (http://www.php.net/manual/en/ref.domxml.php). Sličan API koristi XML_Tree s tim što ne zahteva spomenutu ekstenziju.

mega023
06. 11. 2005., 00:32
pronasao sam ovo
http://minixml.psychogenic.com/index.html

prilicno je jednostavno za upotrebu i radi ono sto meni treba...

edit:

nasao sam i ovo
http://www.engageinteractive.com/mambo/index.php?option=content&task=view&id=3606&Itemid=10137

radi odlicno i sto je najvaznije ima odlican docs
tako da mogu da se snadjem...

mega023
06. 11. 2005., 01:24
evo jednu koju ja koristim :) nije nesto ali vrsi sitan posao :)


<?php
/**
* @class xml2array
*/

class xml2array
{

/**
* constructor
*/
function xml2array( $xml )
{
// check for file
if ( file_exists($xml) )
$xml = file_get_contents( $xml );

// check for string, open in dom
if ( is_string($xml) )
{
$xml = domxml_open_mem( $xml );
$this->root_element = $xml->document_element();
}

// check for dom-creation,
if ( is_object( $xml ) && $xml->node_type() == XML_DOCUMENT_NODE )
{
$this->root_element = $xml->document_element();
//$this->xml_string = $xml->dump_mem(true);
return TRUE;
}

if ( is_object( $xml ) && $xml->node_type() == XML_ELEMENT_NODE )
{
$this->root_element = $xml;
return TRUE;
}

return FALSE;
}

/**
* recursive function to walk through dom and create array
*/
function _recNode2Array( $domnode )
{
if ( $domnode->node_type() == XML_ELEMENT_NODE )
{

$childs = $domnode->child_nodes();
foreach($childs as $child)
{
if ($child->node_type() == XML_ELEMENT_NODE)
{
$subnode = false;
$prefix = ( $child->prefix() ) ? $child->prefix().':' : '';

// try to check for multisubnodes
foreach ($childs as $testnode)
if ( is_object($testnode) )
if ($child->node_name() == $testnode->node_name() && $child != $testnode)
$subnode = true;

if ( is_array($result[ $prefix.$child->node_name() ]) )
$subnode = true;

if ($subnode == true)
$result[ $prefix.$child->node_name() ][] = $this->_recNode2Array($child);
else
$result[ $prefix.$child->node_name() ] = $this->_recNode2Array($child);
}
}

if ( !is_array($result) ){
// correct encoding from utf-8 to locale
// NEEDS to be updated to correct in both ways!
$result['#text'] = html_entity_decode(htmlentities($domnode->get_content(), ENT_COMPAT, 'UTF-8'), ENT_COMPAT,'ISO-8859-15');
}

if ( $domnode->has_attributes() )
foreach ( $domnode->attributes() as $attrib )
{
$prefix = ( $attrib->prefix() ) ? $attrib->prefix().':' : '';
$result["@".$prefix.$attrib->name()] = $attrib->value();
}

return $result;
}
}

/**
* caller func to get an array out of dom
*/
function getResult()
{
if ( $resultDomNode = $this->root_element )
{
$array_result[ $resultDomNode->tagname() ] = $this->_recNode2Array( $resultDomNode );
return $array_result;
} else
return false;
}

function getEncoding()
{
preg_match("~\<\?xml.*encoding=[\"\'](.*)[\"\'].*\?\>~i",$this->xml_string,$matches);
return ($matches[1])?$matches[1]:"";
}

function getNamespaces()
{
preg_match_all("~[[:space:]]xmlns:([[:alnum:]]*)=[\"\'](.*?)[\"\']~i",$this->xml_string,$matches,PREG_SET_ORDER);
foreach( $matches as $match )
$result[ $match[1] ] = $match[2];
return $result;
}
}
?>



mada pokusaj sa codewalkersa ovu
http://codewalkers.com/seecode/185.html



e kako da izvucem podatke
kada u array-u imam jos par nivoa array-a???

Petar Marić
06. 11. 2005., 09:57
@mega023: Prošetaš se i kroz njih ;)
Hijerarhijsku organizaciju ćeš u svakom slučaju dobiti, to je poenta XML-a. Možeš napisati funkciju koja se rekurzivno šeta kroz niz, ili da (ako koristiš DOM ili SAX) to učiniš već za vreme parsiranja XML-a.

@bluesman: Ako imaš PHP5, od srca ti preporučujem SimpleXML ekstenziju - enjoy :)

mega023
06. 11. 2005., 11:29
nemam PHP 5 :(
a vidim da bi to islo MNOGO lakse preko SimpleXML-a

bluesman
06. 11. 2005., 11:45
Imam ja PHP5 ali nema klijent, u tome je problem :)

Nego, hvala na postovima sad cu da pogledam.

bluesman
06. 11. 2005., 12:34
mada pokusaj sa codewalkersa ovu
http://codewalkers.com/seecode/185.html

Ovaj ne radi dobro uvek jer ignorise parametre

<tag attribut="nesto">Value</tag>

I ignorise sve tipa

<ok/>

bluesman
06. 11. 2005., 13:03
pronasao sam ovo
http://minixml.psychogenic.com/index.html

prilicno je jednostavno za upotrebu i radi ono sto meni treba...

edit:

nasao sam i ovo
http://www.engageinteractive.com/mambo/index.php?option=content&task=view&id=3606&Itemid=10137

radi odlicno i sto je najvaznije ima odlican docs
tako da mogu da se snadjem...

MiniXML radi super i ima sve sto mi treba, mada i tu ima 3 klase...

domit! je mnogo vise od XML parsera.

(Ovo sam napisao cisto da imate neki "review" ako ste se vec potrudili da mi pomognete na cemu zahvaljujem :))