1

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');

Kevin
  • 41,694
  • 12
  • 53
  • 70
Andris
  • 1,434
  • 1
  • 19
  • 34

1 Answers1

1

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.

Kevin
  • 41,694
  • 12
  • 53
  • 70
  • All works, thanks! `Id[following-sibling::CategoriesUrl[text() = 'cars']` means: get Id inside node where text of CategoriesUrl of the same node equals to cars? – Andris Jan 13 '15 at 14:50
  • 1
    @user2118559 it simply means get all the nodes with the name `Id` which has a following sibling of `CategoriesUrl` with a text `cars`. Glad this helped – Kevin Jan 14 '15 at 01:08