Hardcoded the "root" and "element" tags in there, so it is working from the structure of your test file in that regard,
Code:
<?php
// mainline
echo "Start of run " . date("M d Y H:i:s", time()) . "<br>\n";
flush();
// define sorter object
$xmlobj=new hd_xml_sorter();
// input file - valid xml file or url to xml feed
$xmlobj->inputfile='test.xml';
// output file name - include path if not the current folder
$xmlobj->outputfile='new_sorted.xml';
// sort fields - order of fields to sort by , type n=numeric, s=string
$xmlobj->sortfields=[['name'=>'age','type'=>'n'],['name'=>'username','type'=>'s']];
// main sort order - first field is controlling field asc is ascending, des is descending. defaulkts ot ascending
$xmlobj->sortorder='asc';
// call to main file process
$xmlobj->hd_sort_file();
echo "Finished " . date("M d Y H:i:s", time()) . "<br>\n";
if(!empty($xmlobj->error_message))
{
echo "There were errors:<br>\n" . $xmlobj->error_message . "<br>\n";
}
echo "Processed " . $xmlobj->process_count . " input records<br>\n";
echo "wrote " . $xmlobj->records_written . " output records<br>\n";
// end of mainline
class hd_xml_sorter
{
public $inputfile='';
public $outputfile='xml_output.xml';
public $sortfields=[];
public $sortorder='asc';
public $records_written=0;
public $process_count=0;
public $error_message='';
private $sortwork=[];
private $sortvals=[];
private $inrec='';
public function hd_sort_file()
{
if(!empty($this->inputfile))
{
$this->hd_get_xml_file($this->inputfile);
if($this->inrec)
{
$this->hd_process_xml($this->sortwork,$this->sortfields);
}
if(count($this->sortwork)>0)
{
$this->hd_sort_xml_file();
}
if(count($this->sortwork)>0)
{
$this->hd_write_xml_file();
}
}
else
{
$this->error_message .="No input filename was given<br>\n";
}
}
private function hd_get_xml_file()
{
$this->inrec=simplexml_load_file($this->inputfile);
if(!$this->inrec)
{
$this->error_message .="Could not get xml feed: " . $this->inputfile . "<br>\n";
}
}
private function hd_process_xml($xmlrec='')
{
$proc_cnt=0;
foreach($this->inrec as $inrec)
{
$this->sortvals=array_fill(0,count($this->sortfields),'');
$this->sortwork[]['sortkey']='';
$outrec='';
$outrec=$this->hd_iterate_xml($inrec, $outrec);
for($i=0;$i<count($this->sortvals);$i++)
{
$this->sortwork[count($this->sortwork)-1]['sortkey'] .=$this->sortvals[$i] . "_";
}
$this->sortwork[count($this->sortwork)-1]['body']=$outrec;
$this->process_count++;
}
}
private function hd_iterate_xml($inrec, $outrec='')
{
foreach($inrec as $key=>$value)
{
$key=str_replace("\n","",$key);
if(count($value)>0)
{
$workrec='';
$workrec .=$this->hd_iterate_xml($value, $workrec);
$outrec .="<" . $key . ">" . $workrec . "</" . $key . ">\n";;
}
else
{
$outrec .="<" . $key . ">" . trim($value) . "</" . $key . ">\n";
$cntr=0;
foreach($this->sortfields as $field)
{
if($field['type']=='s')
{
$val2use='';
}
else
{
$val2use='0';
}
//echo "field name=" . $field['name'] . " key=" . $key . "<br>\n";
if($key==$field['name'])
{
if($field['type']=='s')
{
$val2use=trim($value);
}
else
{
$val2use=trim(strval($value));
}
$this->sortvals[$cntr]=$val2use;
}
$cntr++;
}
}
}
return $outrec;
}
private function hd_sort_xml_file()
{
foreach ($this->sortwork as $key => $row)
{
$sortkey[]['key'] = $row['sortkey'];
}
if($this->sortorder=='des')
{
array_multisort($sortkey, SORT_DESC, $this->sortwork);
}
else
{
array_multisort($sortkey, SORT_ASC, $this->sortwork);
}
}
private function hd_write_xml_file()
{
$outfile=fopen($this->outputfile,'w');
fwrite($outfile,'<' . '?xml version="1.0" encoding="utf-8" ?' . ">\n");
fwrite($outfile,"<root>\n");
for($i=0;$i<count($this->sortwork);$i++)
{
fwrite($outfile,"<element>\n");
fwrite($outfile,$this->sortwork[$i]['body']);
fwrite($outfile,"</element>\n");
$this->records_written++;
}
fwrite($outfile,"</root>\n");
fclose($outfile);
}
}
?>
.