Sorting XML Data without XSLT

wxdqz

New Member
For those of you who need to sort XML data results without XSLT, here is a handly little function that I created:


<?php

// #########################################
// Function: xml_sort
// Sorts XML Data by Attribute or tag
// #########################################

function xml_sort($dom,$path,$dir=SORT_ASC,$mode=SORT_REGULAR){
$assigned=Array();
preg_match_all("/\[(@?\w*)\]/",$path,$out,PREG_PATTERN_ORDER);
$search=$out[1][0];
$att=preg_match("/^@/",$search) ? preg_replace("/^@/","",$search) : "";

$xPath=$dom->xpath_new_context();
$xResult=$xPath->xpath_eval($path);

if(sizeof($xResult->nodeset>0)){

$newresult=domxml_new_doc("1.0");
$newlist=$newresult->xpath_new_context();

foreach($xResult->nodeset as $node){
if($att==""){
$value=$node->get_elements_by_tagname($search);
$value=$value[0]->get_content();
}else{
$value=$node->get_attribute($att);
}
$temp[]=$value;
}

is_array($temp) ? $dir==4 ? sort($temp,$mode) : rsort($temp,$mode) : null;

foreach($temp as $item){

foreach($xResult->nodeset as $node){
preg_match_all("/1;i:([0-9]*)/",serialize($node),$out,PREG_PATTERN_ORDER);
$serial=$out[1][0];
if($att==""){
$data=$node->get_elements_by_tagname($search);

if($item==$data[0]->get_content()){
if(!in_array($serial,$assigned)){
$newlist->nodeset[]=$node;
$assigned[]=$serial;
}
}
}else{
if($item==$node->get_attribute($att)){
if(!in_array($serial,$assigned)){
$newlist->nodeset[]=$node;
$assigned[]=$serial;
}
}
}
}
}
}

return $newlist;
}


// Example Usage

$xml=<<<EOF
<?xml version="1.0"?>
<pages>
<page title="craig" id="1">
<name>test</name>
<email>[email protected]</email>
</page>
<page title="fred" id="2">
<name>farms</name>
<email>[email protected]</email>
</page>
<page title="ickypoo" id="4">
<name>icky</name>
<email>[email protected]</email>
</page>
<page title="mosesd" id="3">
<name>moses</name>
<email>[email protected]</email>
</page>
</pages>
EOF;

$domXML=domxml_open_mem($xml);

$sorted=xml_sort($domXML,"/pages/page[@id]",SORT_ASC,SORT_NUMERIC);

foreach($sorted->nodeset as $node){
print $node->get_attribute("title")."<br>";
}

?>
 
Back
Top