2

i have an xml file which contains around 60 books which i need to put into ascending order from the borrowedcount using php so far my code shows all the books but will not sort? any help would be really appriecated

PHP

<?php


$xmlassignDoc = new DOMDocument();
$xmlassignDoc->load("books.xml");


$books = $xmlBookDoc->getElementsByTagName("item");

foreach($books as $list)
{
    $course = $list->getElementsByTagName("course");
    $course = $course->item(0)->nodeValue;


//HERE is where the GET function will be
    if ($course == "CC150")
    {

    print_r($array);
        $id = $list->getAttribute("id");
        echo "<b>Book ID: </b> $id <br>";

         $title = $list->getElementsByTagName("title");
         $title = $title->item(0)->nodeValue;
         echo "<b>Title: </b> $title <br>";

         $isbn = $list->getElementsByTagName("isbn");
         $isbn = $isbn->item(0)->nodeValue;
         echo "<b>ISBN: </b> $isbn <br>";

         $borrowed = $list->getElementsByTagName("borrowedcount");
         $borrowed = $borrowed->item(0)->nodeValue;
         echo "<b>Borrowed Count: </b> $borrowed <br>";
         echo "<br>";
    } 
}
//print $xmlBookDoc->saveXML();
?>

xml file

<?xml version="1.0" encoding="utf-8"?>
<bookcollection>
<items>
  <item id="51390">
     <title>Management of systems development /</title>
     <isbn>0091653215</isbn>
     <url>http://library.hud.ac.uk/catlink/bib/51390</url>
     <borrowedcount>45</borrowedcount>
     <courses>
        <course>CC140</course>
        <course>CC210</course>
     </courses>
  </item>
  <item id="483">
     <title>Database systems management and design /</title>
     <isbn>0877091153</isbn>
     <url>http://library.hud.ac.uk/catlink/bib/483</url>
     <borrowedcount>28</borrowedcount>
     <courses>
        <course>CC140</course>
     </courses>
  </item>
  <item id="585842">
     <title>E-learning skills /</title>
     <isbn>0230573126</isbn>
     <url>http://library.hud.ac.uk/catlink/bib/585842</url>
     <borrowedcount>5</borrowedcount>
     <courses>
        <course>CC157</course>
     </courses>
  </item>

Dan Davies
  • 73
  • 1
  • 1
  • 7
  • You can't expect the XML file to be sorted if you don't implicitly write some code that will sort it. Try to change that loop of yours so that it saves all the values into an array and then use a custom sort function where you can choose which column to sort on. – silkfire Feb 19 '13 at 12:31
  • sorry forgot to write that in i did try ksort etc but it wasnt working so deleted the code thats just what i have so far – Dan Davies Feb 19 '13 at 12:34
  • What's this for? `if ($course == "CC150")`; are you also filtering based on course? – Ja͢ck Feb 19 '13 at 13:01
  • Jack ive got to add user input so they can input different courses which would then display th books from that course in ascending order of borrowedcount – Dan Davies Feb 22 '13 at 12:53

2 Answers2

4

My solution:

$books = array();

$xml = simplexml_load_file('books.xml'); 

foreach($xml->items->item as $item) {
    $books[] = array(
                     'id'             => (string)$item->attributes()->id,
                     'title'          => (string)$item->title,
                     'isbn'           => (string)$item->isbn,
                     'course'         => (string)$item->courses->course[0],
                     'borrowed_count' => intval($item->borrowedcount)
                    );
}


array_sort_by_column($books, 'borrowed_count');

var_dump($books);

And the sorting function:

function array_sort_by_column(&$array, $column, $direction = SORT_ASC) {
    $reference_array = array();

    foreach($array as $key => $row) {
        $reference_array[$key] = $row[$column];
    }

    array_multisort($reference_array, $direction, $array);
}
silkfire
  • 24,585
  • 15
  • 82
  • 105
1

file '1.php':

<?php
include 'books.php';
$b=new books();
$arr=$b->load('books.xml');         //1. load books from xml to array
usort($arr, array('books','cmp'));  //2. sort array
$b->save('out.xml',$arr);           //3. save array to xml
?>

file 'books.php':

<?php
  class books
  {
     //load books from xml to array
     public function load($fname)
     {
        $doc=new DOMDocument();

        if($doc->load($fname))  $res=$this->parse($doc);
        else                    throw new Exception('error load XML');

        return $res;
     }


     static public function cmp($a, $b)
     {
         if ($a['fields']['borrowedcount'] == $b['fields']['borrowedcount']) {
             return 0;
         }
         return ($a['fields']['borrowedcount'] < $b['fields']['borrowedcount']) ? -1 : 1;
     }


     private function parse($doc)
     {
        $xpath = new DOMXpath($doc);
        $items = $xpath->query("items/item");
        $result = array();
        foreach($items as $item)
        {
           $result[]=array('id'=>$item->getAttribute('id'), 'fields'=>$this->parse_fields($item));
        }
        return $result;
     }


     private function parse_fields($node)
     {
        $res=array();
        foreach($node->childNodes as $child)
        {
           if($child->nodeType==XML_ELEMENT_NODE)
           {
              $res[$child->nodeName]=$this->get_value($child);
           }
        }

        return $res;
     }

     private function get_value($node)
     {
        if($node->nodeName=='courses')
        { 
           $res=array();
           foreach($node->childNodes as $child)
           {
              if($child->nodeType==XML_ELEMENT_NODE)
              {
                 $res[]=$child->nodeValue;
              }
           } 
           return $res;
        }
        else
        {
           return $node->nodeValue;
        }
     }

     //save array to xml
     public function save($fname, $rows)
     {
        $doc = new DOMDocument('1.0','utf-8');
        $doc->formatOutput = true;

        $bc = $doc->appendChild($doc->createElement('bookcollection'));
        $items = $bc->appendChild($doc->createElement('items'));

        foreach($rows as $row)
        {
           $item=$items->appendChild($doc->createElement('item'));
           $item->setAttribute('id',$row['id']);
           foreach($row['fields'] as $field_name=>$field_value)
           {
              $f=$item->appendChild($doc->createElement($field_name));
              if($field_name=='courses')
              {
                 foreach($field_value as $course_val)
                 {
                    $course=$f->appendChild($doc->createElement('course'));
                    $course->appendChild($doc->createTextNode($course_val));
                 }
              }
              else
              {
                 $f->appendChild($doc->createTextNode($field_value));
              }

           }
        }

        file_put_contents($fname, $doc->saveXML());
     }

  }
?>
realization
  • 587
  • 1
  • 4
  • 5