Już szukam. Dam znać

Muszę przyznać, że jestem troche zawiedziony całym zamieszaniem wokół XML, a raczej odczuciem chaosu spowodowanym brakiem (jak dla mnie) przejrzystych ścieżek poznania aparatu jego obsługi. rzeczywiście znalazłem wiele klas opartych na DOM XML, ale za kazdym razem i tak trzeba było ingerować w logikę DOM więc bez znajomości DOm XML taka klasa mi sie nie przyda. Czytanie o DOM XML na php.net przypomina mi tą reklamę z " .... ntfs z jakims lewarowaniem" na co klient wybałusza gały ... :/ Po prostu o ile sam XML jest strukturalnie poukładany o tyle na ironię dokumentacja o narzędziach do niego jest chaotyczna.
Reasumując. Przejrzałem na php.net przykłady oparte na klasycznych funkcjach XML'owych php, i po drobnych modyfikacjach mam to czego chciałem. Mam dwie klasy - jedna odpowiada za odwzorowanie wyrażenia xml na hierarchiczną tablicę i drugą o działaniu odwrotnym tak żeby zmodyfikowaną tablice można było z powrotem zapisac jako XML.
Nie znam się specjalnie na XML. Testowałem je na plikach worda zapisanych w formacie XML i działają.
Poniżej klasy:
xml do tablicy
<?php
/*
Klasa przetwarzająca wyrażenie XML na tablicę z zachowanie hierarchii, atrybutów
i namespace's (przynajmniej tam gdzie używałem - xml worda)
Znalazłem to na php.net, dodałem tylko opcje zachowania wielkości liter
Klasa korzysta ze standardowych funkcji pbsługi XML więc nie potrzeba DOM XML it
p.
$objXML = new xml2Array();
$arrOutput = $objXML->parse($strYourXML);
print_r($arrOutput);
*/
class xml2Array {
var $arrOutput = array(); var $resParser;
var $strXmlData;
function parse($strInputXML) {
$this->resParser = xml_parser_create ();
xml_parser_set_option($this->resParser , XML_OPTION_CASE_FOLDING, 0);
//xml_parser_set_option($this->resParser , XML_OPTION_SKIP_WHITE, 1);
xml_set_object($this->resParser,$this);
xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
xml_set_character_data_handler($this->resParser, "tagData");
$this->strXmlData = xml_parse($this->resParser,$strInputXML );
if(!$this->strXmlData) {
xml_error_string(xml_get_error_code($this->resParser)),
xml_get_current_line_number($this->resParser)));
}
xml_parser_free($this->resParser);
return $this->arrOutput;
}
function tagOpen($parser, $name, $attrs) {
$tag=array("name"=>$name,"attrs"=>$attrs); }
function tagData($parser, $tagData) {
if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) { $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $tagData; }else {
$this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData; }
}
}
function tagClosed($parser, $name) {
$this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1
]; }
}
?>
z tablicy do XML:
<?php
/*
Klasa o działaniu odwrotnym do xml2Array przetwarzająca tablicę na wyrażenie XML
z zachowanie hierarchii, atrybutów i namespace's (przynajmniej tam gdzie używałem - xml worda)
Znalazłem to na php.net, ale był problem z wartościami tagów (gineły) więc trochę kod rozwinąłem
Klasa korzysta ze standardowych funkcji pbsługi XML więc nie potrzeba DOM XML it
p.
$objXML = new Array2xml();
$xmlOutput = $objXML->parse($array);//$array[0] jeśli tablica jest zwrócona przez klasę xml2Array :)
print_r($xmlOutput);
*/
class Array2xml{
function parse($root){
$curr_name = $root['name'];
$attribs = $root['attrs'];
$curr_childs = $root['children'];
$curr_data = $root['cdata'];
$curr_tagdata=$root['tagData'];
$xml .= '<'.$curr_name;
$i = 1;
foreach($attribs as $key => $value){
$curr_attribs .= $key.'="'.$value.'"';
$i++;
if($i <= count($attribs)){ $curr_attribs .= ' ';
}
}
$xml .= ' '.$curr_attribs;
}
if($curr_data != ''){
$xml .= '><![CDATA['.$curr_data.']]></'.$curr_name.'>';
}else {
if(count($curr_childs) > 0
){ $xml .= '>';
if($curr_tagdata) $xml.=$curr_tagdata;
foreach($curr_childs as $child){
$xml .= $this->parse($child);
}
$xml .= '</'.$curr_name.'>';
} else {
if($curr_tagdata){
$xml.='>';
$xml.=$curr_tagdata;
$xml .= '</'.$curr_name.'>';
}else{
$xml .= '/>';
}
}
}
}
return $xml;
}
}
?>
Mając takie wyrażenie XML:
<root xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" >
<w:ocean >spokojny
<morze >czerwone</morze>
<morze >czarne</morze>
</w:ocean>
<kontynent >
<o:kraj >Polska</o:kraj>
</kontynent>
</root>
dostajemy taką tablicę:
Array
(
[0] => Array
(
[name] => root
[attrs] => Array
(
)
[children] => Array
(
[0] => Array
(
[name] => w:ocean
[attrs] => Array
(
)
[tagData] => spokojny
[children] => Array
(
[0] => Array
(
[name] => morze
[attrs] => Array
(
)
[tagData] => czerwone
)
[1] => Array
(
[name] => morze
[attrs] => Array
(
)
[tagData] => czarne
)
)
)
[1] => Array
(
[name] => kontynent
[attrs] => Array
(
)
[children] => Array
(
[0] => Array
(
[name] => o:kraj
[attrs] => Array
(
)
[tagData] => Polska
)
)
)
)
)
)