Acquisition Category structure of the XML feed
How a simple get a structure of menu from eshop from shop’s XML for feed aggregators?
XML feed does not contain category itself, but contains nested items in categories. The categories separate any separator.
We will assume that we have all the categories stored in an array of values (XML load will not solve), The array includes all categories, separated by any separator. We know the separator.
Solution in PHP
Input data:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 |
//input array $array = array( "0" => "Books", "1" => "Books > Development", "2" => "Books > Cars", "3" => "Books > Cars > Audi", "4" => "Books > Cars > BMW", "5" => "Books > Cars > Aston Martin", "6" => "Books > Development > Ruby", "7" => "Books > Development > C++", "8" => "Books > Development > PHP"); |
Data processing
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
//set delimiter $delimiter = '>'; //prepare output array $out_array = array(); //browse array item by item foreach( $array as $value ){ //trim value $value = trim( $value ); //if value exists (can be empty) if( $value ){ //explode value by delimiter $ex = explode($delimiter, $value ); //prepare output array $str = '$out_array'; //browse exploded array item by item foreach( $ex as $id => $item ){ //add new array into basic array $ex[$id] = (trim($item)); $str .= '[$ex[' . $id . ']]'; } $str .= ' = NULL;'; //create array - evaluate string eval( $str ); } } |
Extract the structure – only for demonstration
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$item_id = 0; function getOutput( $array, $position = 0, $parent = 0){ global $item_id; foreach( $array as $id => $value ){ $item_id++; echo '<tr> <td>' . $item_id . '</td> <td style="padding-left: ' . ( $position * 10) . '"> |- ' . $id , '</td> <td>' . $parent . '<td> </tr>'; if( is_array( $value ) ){ //call recursive getOutput($value, $position + 1, $item_id ); } } } echo '<table>'; echo '<tr><th>ID</th><th>NAME</th><th>PARENT ID</th></tr>'; getOutput($out_array, 0); echo '</table>'; |
Sample output:
Solution in Ruby
Input data:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 |
#input array array = { "0" => "Books", "1" => "Books > Development", "2" => "Books > Cars", "3" => "Books > Cars > Audi", "4" => "Books > Cars > BMW", "5" => "Books > Cars > Aston Martin", "6" => "Books > Development > Ruby", "7" => "Books > Development > C++", "8" => "Books > Development > PHP" } |
Data processing
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#delimiter delimiter = ">" #recursively combines two hashes together! def reversemerge h1, h2 #we will use the classical merge, but also recursively call again if it has more elements than the value zero h2.merge!(h1){|k,v1,v2| (h1.length > 0 || h2.length() > 0 ? reversemerge( v1, v2) : { v1 , v2 } ) } end #convert array into hash def arraytohash array, i_d = 0 #setup default value value = {} #if exists next item, will be used like next hash value {val => {..}} if( array[i_d + 1]) #call recursive the same function value = arraytohash array, (i_d +1) end #return hash {array[i_d].strip => value} end #define new hash out_array_final = {} #go through the input array with values array.each { |key, value| #udelame explode hodnot podle separatoru ex = value.split(">") #if item exists if ex.length && ex[0] #create a hash where are values ??as keys: {val => {val => { val => {...}}}} out_array_temp = arraytohash ex #if exists this hash if out_array_temp.length #attach it to the final array out_array_final = reversemerge out_array_final, out_array_temp end end } |
Extract the structure – only for demonstration
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
################ output #################### #create spaces #crap function :-) def getSpace pos " ".slice(0, pos*2) + "|- " end #write array - it's just for example def getOutput array, position = 0 array.each { |key, value| print getSpace(position) print key print "n" if value.class == Hash getOutput value, position+1 end } end getOutput out_array_final |
Sample output:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 |
>ruby getStructure.rb |- Books |- Cars |- BMW |- Audi |- Aston Martin |- Development |- PHP |- C++ |- Ruby >Exit code: 0 |
Posted on 28 October 2012