Search code examples
phpxmlxpathsimplexml

php - xml. Is it possible to access particular xml node without looping through all data of xml file


Xml file like this

<xml>

<Categories>
<OneSubcategory>

<Id>4</Id>
<CategoriesUrl>cars</CategoriesUrl>

<Id>5</Id>
<CategoriesUrl>staff-required</CategoriesUrl>

</OneSubcategory>
</Categories>

</xml>

Want to get value of <Id> where <CategoriesUrl> is cars

Now i do this

1) $xml = simplexml_load_file( filename.xml' );

2) then loop through all file

foreach($xml->children() as $subcategory){
  if( trim($subcategory->OneSubcategory->CategoriesUrl) == 'cars' ){
  $id = trim($subcategory->OneSubcategory->Id);
  }
}

Is it possible to get the value without looping, like mysql SELECT Id WHERE CategoriesUrl = 'cars'?

Update

Based on this http://www.tuxradar.com/practicalphp/12/3/3#null

With $id = $xml->xpath('Categories/OneSubcategory/Id'); get array of all Id

Tried $id = $xml->xpath('Categories/OneSubcategory/Id[CategoriesUrl="cars"]'); Get empty array

What is incorrect?

Seems this is a solution

$id = $xml->xpath('Categories/OneSubcategory[CategoriesUrl="cars"]/Id');


Solution

  • The query seems off since CategoriesUrl and Id are siblings. If you do not want to loop then just explicitly set the index to zero to get the first value.

    $query = "//Id[following-sibling::CategoriesUrl[text() = 'cars']]";
    $nodes = $xml->xpath($query);
    if(count($nodes) > 0) { // if found
        // get one
        $id = $nodes[0];
        echo $id;
    
        // if you want to loop
        // foreach($nodes as $node) { // loop all results
        //  $id = (string) $node;
        //  echo $id;
        // }
    }
    

    If you want all results found, then just use foreach.