Search code examples
phparraysobjectsimplexml

simplexml objects and arrays within each other


I have a simplexml script which creates a complex object, I just want the information from within the div 'grid' so grab I use xpath to get it.

$id = $sxml->xpath("//*[@id='grid_data']");

This results in big object array which seems to be a mix of objects and arrays and im really struggling to traverse my way through it. The below is a very cut down version. There are 30 members 'Person 1' etc. Each person has a list which contains 25 items and its these I need to access/work on. (["li"]=> array(25))

Ideally I need to loop through each member, and then subsequently loop through each li item, but im getting hung up on using $variable['name'] vs $object->name

Just testing I have tried a variety of ways to get the persons name and I think Im confusing myself trying to wrap my head around objects traversal.

echo $id[0]->div[0][p][a];
echo $id[0]['div'][0]['p']['a'];
echo $id->0->div

array(1) {
  [0]=>
  object(SimpleXMLElement)#3 (2) {
    ["@attributes"]=>
    array(1) {
      ["id"]=>
      string(9) "grid_data"
    }
    ["div"]=>
    array(35) {
      [0]=>
      object(SimpleXMLElement)#4 (4) {
        ["@attributes"]=>
        array(1) {
          ["class"]=>
          string(9) "stff_grid"
        }
        ["p"]=>
        object(SimpleXMLElement)#39 (2) {
          ["@attributes"]=>
          array(2) {
            ["class"]=>
            string(16) "staff"
            ["id"]=>
            string(15) "1328"
          }
          ["a"]=>
          string(17) "Person 1"
        }
        ["ul"]=>
        object(SimpleXMLElement)#40 (2) {
          ["@attributes"]=>
          array(1) {
            ["class"]=>
            string(0) ""
          }
          ["li"]=>
          array(25) {
            [0]=>
            object(SimpleXMLElement)#42 (2) {
              ["@attributes"]=>
              array(1) {
                ["class"]=>
                string(16) "lrge"
              }
              ["a"]=>
              string(2) "00"
            }
            [1]=>
            object(SimpleXMLElement)#43 (2) {
              ["@attributes"]=>
              array(1) {
                ["class"]=>
                string(16) "lrge"
              }
              ["a"]=>
              string(2) "01"
            }
            [2]=>
            object(SimpleXMLElement)#44 (2) {
              ["@attributes"]=>
              array(1) {
                ["class"]=> 
                string(16) "lrge"
              }
              ["a"]=> 
              string(2) "02"
            }
          }
        }
        ["div"]=>
        object(SimpleXMLElement)#41 (1) {
          ["@attributes"]=>
          array(1) {
            ["class"]=>
            string(10) "left"
          }
        }
      }
      [1]=>
      object(SimpleXMLElement)#5 (4) {
        ["@attributes"]=>
        array(1) {
          ["class"]=>
          string(9) "stff_grid"
        }
        ["p"]=>
        object(SimpleXMLElement)#41 (2) {
          ["@attributes"]=>
          array(2) {
            ["class"]=>
            string(16) "staff"
            ["id"]=>
            string(15) "no_1333"
          }
          ["a"]=>
          string(11) "Person 2"
        }
        ["ul"]=>
        object(SimpleXMLElement)#40 (2) {
          ["@attributes"]=>
          array(1) {
            ["class"]=>
            string(0) ""
          }
          ["li"]=>
          array(25) {
            [0]=>
            object(SimpleXMLElement)#66 (2) {
              ["@attributes"]=>
              array(1) {
                ["class"]=>
                string(16) "lrge"
              }
              ["a"]=>
              string(2) "00"
            }
            [1]=>
            object(SimpleXMLElement)#65 (2) {
              ["@attributes"]=>
              array(1) {
                ["class"]=>
                string(16) "lrge"
              }
              ["a"]=>
              string(2) "01"
            }
            [2]=>
            object(SimpleXMLElement)#64 (2) {
              ["@attributes"]=>
              array(1) {
                ["class"]=>
                string(16) "lrge"
              }
              ["a"]=>
              string(2) "02"
            }
          }
        }
        ["div"]=>
        object(SimpleXMLElement)#39 (1) {
          ["@attributes"]=>
          array(1) {
            ["class"]=>
            string(10) "left"
          }
        }
      }
      [2]=>
      object(SimpleXMLElement)#6 (1) {
        ["@attributes"]=>
        array(1) {
          ["class"]=>
          string(6) "spacer"
        }
      }

Solution

  • Let's use simplexml along with xpath, see comments inline below

    <?php
    $xml = simplexml_load_file('xml.xml');
    
    // let's take all the divs that have the class "stff_grid"
    $divs = $xml->xpath("//*[@class='stff_grid']");
    
    // for each of these elements, let's print out the value inside the first p tag
    foreach($divs as $div){
        print $div->p->a . PHP_EOL;
    
        // now for each li tag let's print out the contents inside the a tag
        foreach ($div->ul->li as $row){
            print "  - " . $row->a . PHP_EOL;
        }
    }
    /* this outputs the following
    Person 1
      - 1 hr
      - 2 hr
      - 3 hr
      - 4 hr
      - 5 hr
      - 6 hr
      - 7 hr
      - 8 hr
    Person 2
      - 1 hr
      - 2 hr
      - 3 hr
      - 4 hr
      - 5 hr
      - 6 hr
      - 7 hr
      - 8 hr
    Person 3
      - 1 hr
      - 2 hr
      - 3 hr
      - 4 hr
      - 5 hr
      - 6 hr
      - 7 hr
      - 8 hr
    */