Sort XML via attribute value PHP

后端 未结 6 719
忘掉有多难
忘掉有多难 2020-12-01 20:25

So I have an XML file that I am trying to loop through in order, according to the attribute, \"order\".

Here is an example:




        
相关标签:
6条回答
  • 2020-12-01 20:31

    I got the solution of xml sorting using attributes in PHP.

    Please visit Below URL:-

    http://ewebsurf.blogspot.com/2010/12/xml-sorting-using-attributes-php.html

    0 讨论(0)
  • 2020-12-01 20:32

    This should give you what you want:

    $string = <<<EOS
    <page>
    <talentTrees>
    <tree name="Football" order="2" />
    <tree name="Baseball" order="0" />
    <tree name="Frisbee" order="1" />
    </talentTrees>
    </page>
    EOS;
    
    $xml = simplexml_load_string($string);
    
    $trees = $xml->xpath('/page/talentTrees/tree');
    function sort_trees($t1, $t2) {
        return strcmp($t1['order'], $t2['order']);
    }
    
    usort($trees, 'sort_trees');
    var_dump($trees);
    

    $trees are now sorted by the order attribute.

    0 讨论(0)
  • 2020-12-01 20:37

    I wrote a recursive, expanded version that will sort by any number of attributes, in order:

    //sort_xml_by_attr($simplexmlobject,array('attr_one','attr_two','attr_three'))
    
      class SortXML {
        public $xml;
        var $attr;
        function SortXML($xml,$attr) {
          $this->xml = $xml;
          $this->attr = $attr;
        }
        function cmp_attr($a,$b) {
          $a1 = (string)$a->xml[(string)$a->attr];
          $b1 = (string)$b->xml[(string)$b->attr];
          if (is_numeric($a1) && is_numeric($b1)) {
            if (is_float($a1) && is_float($b1)) {
              $a1 = (float)$a1;
              $b1 = (float)$b1;
            } else {
              $a1 = (int)$a1;
              $b1 = (int)$b1;
            }
          }
          if ($a1 == $b1) return 0;
          return ($a1 > $b1) ? +1 : -1;
        }
      }
    
      function sort_xml_by_attr($xml_obj,$attr) {
        if (count($attr)>1) {
          // break up array by unique values of the first attribute in the list
          $unique_attrs = array();
          foreach ($xml_obj as $i) $unique_attrs[] = (string)$i[$attr[0]];
          $unique_attrs = array_unique($unique_attrs);
          sort($unique_attrs);
          // create an array of arrays who share a unique attribute value
          foreach ($unique_attrs as $i) {
            foreach ($xml_obj as $p) {
              if ($p[$attr[0]] == $i) $xml_arrays[$i][] = $p;
            }
          }
          // remove first element to progress the recursion to the next attribute
          array_shift($attr); 
          $new_array = array();
          // concatenate sorted arrays
          foreach ($xml_arrays as $i) {
            $new_array = array_merge($new_array,sort_xml_by_attr($i,$attr));
          }
          return $new_array;
        } else {
          // create wrapper objects with new comparison function 
          foreach ($xml_obj as $i) $new_obj[] = new SortXML($i,$attr[0]);
          usort($new_obj,array('SortXML','cmp_attr'));
          foreach ($new_obj as $i) $sorted_obj[] = $i->xml;
          return $sorted_obj;
        }
      }
    
    0 讨论(0)
  • 2020-12-01 20:40

    If you have many elements like this

    $string = <<<EOS
    <page>
    <talentTrees>
    <tree name="Football" order="2" />
    <tree name="Baseball" order="0" />
    <tree name="Frisbee" order="1" />
    </talentTrees>
    <talentTrees>
    <tree name="Football2" order="1" />
    <tree name="Baseball2" order="2" />
    <tree name="Frisbee2" order="0" />
    </talentTrees>
    </page>
    EOS;
    

    You can use foreach:

    $xml = simplexml_load_string($string);
    
    function sort_trees($t1, $t2) {
        return $t1['order'] - $t2['order'];
    }
    
    foreach($xml->talentTrees as $talentTrees){
        foreach($talentTrees->tree as $tree){
        $trees[]= $tree;
        }
        usort($trees, 'sort_trees');
        print_r($trees);
        unset($trees);
    }
    

    output:

    Array
    (
        [0] => Array
            (
                [0] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => Baseball
                                [order] => 0
                            )
    
                    )
    
                [1] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => Frisbee
                                [order] => 1
                            )
    
                    )
    
                [2] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => Football
                                [order] => 2
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [0] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => Frisbee2
                                [order] => 0
                            )
    
                    )
    
                [1] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => Football2
                                [order] => 1
                            )
    
                    )
    
                [2] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => Baseball2
                                [order] => 2
                            )
    
                    )
    
            )
    
    )
    

    For another example: https://stackoverflow.com/a/44379495/3506219

    0 讨论(0)
  • 2020-12-01 20:48

    This page gives some great examples which I thin you could use

    0 讨论(0)
  • 2020-12-01 20:54

    For future reference, here's something you can use to query nodes via XPath and sort the result via XPath as well: SimpleDOM. In this example, I sort all <tree/> nodes by values of the order attribute:

    include 'SimpleDOM.php';
    
    $page = simpledom_load_string('<page>
        <talentTrees>
            <tree name="Football" order="2"/>
            <tree name="Baseball" order="0"/>
            <tree name="Frisbee" order="1"/>
        </talentTrees>
    </page>');
    
    $nodes = $page->sortedXPath('//tree', '@order');
    
    foreach ($nodes as $node)
    {
        echo $node->asXML(), "\n";
    }
    
    0 讨论(0)
提交回复
热议问题