Simplexml: Selecting Elements Which Have a Certain Attribute Value

SimpleXML: Selecting Elements Which Have A Certain Attribute Value

Try this XPath:

/object/data[@type="me"]

Which reads as:

  • Select (/) children of the current element called object
  • Select (/) their children called data
  • Filter ([...]) that list to elements where ...
    • the attribute type (the @ means "attribute")
    • has the text value me

So:

$myDataObjects = $simplexml->xpath('/object/data[@type="me"]');

If object is not the root of your document, you might want to use //object/data[@type="me"] instead. The // means "find all descendents" rather than "find all children".

Use SimpleXML to select content of one node by its attribute

This outputs the expected Hello for me :

$string = <<<XML
<translation>
<home>
<button name="aaa">Hello</button>
<button name="bbb">World</button>
</home>
<office>
<button name="ccc">Foo</button>
<button name="ddd">Bar</button>
<string name="xxx">Sample</string>
</office>
</translation>
XML;
$xml = new SimpleXMLElement($string);
$data = $xml->xpath("//home/button[@name='aaa']")[0];
echo $data;

eval.in demo

SimpleXML xpath to element with certain attribute value?

Add double slashes to the beginning of your xpath:

$source = <<<X
<item>
<custom-attributes>
<custom-attribute attribute-id="taco">false</custom-attribute>
<custom-attribute attribute-id="htmlContent" xml:lang="en-US">testValue</custom-attribute>
<custom-attribute attribute-id="htmlContent" xml:lang="default">testing123</custom-attribute>
</custom-attributes>
</item>
X;

$xml = new SimpleXMLElement($source);

$taco = $xml->xpath("//custom-attribute[@attribute-id='taco']")[0];
$htmlContentArray = $xml->xpath("//custom-attribute[@attribute-id='htmlContent']");

echo "taco : ", $taco, PHP_EOL;
echo "htmlContent: ", implode(', ', $htmlContentArray), PHP_EOL;

Output:

taco       : false
htmlContent: testValue, testing123

Update

For your question in the comments, regarding searching within an item node; you can use .// to start the search from the current node.

// Find an item, then do an xpath on the result of that
// to find the custom attribute element.
// <items> tag added as <item> would otherwise be the root element,
// which would make the example quite pointless.
$source = <<<X
<items>
<item>
<custom-attributes>
<custom-attribute attribute-id="taco">false</custom-attribute>
<custom-attribute attribute-id="htmlContent" xml:lang="en-US">testValue</custom-attribute>
<custom-attribute attribute-id="htmlContent" xml:lang="default">testing123</custom-attribute>
</custom-attributes>
</item>
<item>
<custom-attributes>
<custom-attribute attribute-id="taco">true</custom-attribute>
<custom-attribute attribute-id="htmlContent" xml:lang="en-US">item 2 testValue</custom-attribute>
<custom-attribute attribute-id="htmlContent" xml:lang="default">item 2 testing456</custom-attribute>
</custom-attributes>
</item>
</items>
X;

$xml = new SimpleXMLElement($source);

$item = $xml->item[1]; // Get second item
$taco = $item->xpath(".//custom-attribute[@attribute-id='taco']");
$htmlContentArray = $item->xpath(".//custom-attribute[@attribute-id='htmlContent']");

echo "taco from second item: ", $taco[0], PHP_EOL;
echo "html from second item: ", implode(', ', $htmlContentArray), PHP_EOL;

Output:

taco from second item: true
html from second item: item 2 testValue, item 2 testing456

Simple XML - How to select all elements which have a specific attribute value

Your "SQL":

SELECT reservations->reservation['seat'] FROM performances->performance['id=2']

can be reformulated as:

FROM performances->performance['id=2'] SELECT reservations->reservation['seat'] 

can be reformulated as XPath:


//performances/performance[@id=2]/reservations/reservation/@seat

Ant that's what you need. Look at SimpleXML's xpath() method.

Selecting attribute values based on another attribute value with SimpleXML

$icons->icon will give you a SimpleXMLElement object that gives access to all icon child-elements of the $icons object.

From there you need to select which icon you want to get the attribute for. That works with array-like access and a numeric value for the zero-index child element and a string value for the attribute:

// specify what icon you want (third)
// and the attribute (href)
$icons->icon[2]['href'];

You find that documented in the PHP manual with the SimpleXML basic examples (Example #3 and Example #5).

However this does not work if the position of the element you look for changes. So it's suggested that you use a more specific xpath-expression instead.

php simplexml get a specific item based on the value of a field

Here are 2 simple ways of doing what you want, one is iterating with each item like this:

<?php
$str = <<<XML
<items>
<item>
<title>blah blah 43534</title>
<id>43534</id>
</item>
<item>
<title>blah blah 12437</title>
<id>12437</id>
</item>
<item>
<title>blah blah 7868</title>
<id>7868</id>
</item>
</items>
XML;

$data = new SimpleXMLElement($str);
foreach ($data->item as $item)
{
if ($item->id == 12437)
{
echo "ID: " . $item->id . "\n";
echo "Title: " . $item->title . "\n";
}
}

Live DEMO.

The other would be using an XPath, to pin point the exact data you want like this:

<?php
$str = <<<XML
<items>
<item>
<title>blah blah 43534</title>
<id>43534</id>
</item>
<item>
<title>blah blah 12437</title>
<id>12437</id>
</item>
<item>
<title>blah blah 7868</title>
<id>7868</id>
</item>
</items>
XML;

$data = new SimpleXMLElement($str);
// Here we find the element id = 12437 and get it's parent
$nodes = $data->xpath('//items/item/id[.="12437"]/parent::*');
$result = $nodes[0];
echo "ID: " . $result->id . "\n";
echo "Title: " . $result->title . "\n";

Live DEMO.

simpleXML get node child based on attribute

Simply loop the poster elements and remember to cast the attribute values to strings, since you want to compare them (and probably output them) as strings:

$xml = simplexml_load_file('PosterData.xml');

foreach ($xml->poster as $poster) {
if ((string) $poster['id'] == 'minwage') {
echo (string) $poster->full_image['url'];
}
}

Simplexml get node by attribute

Try using DomDocument:

$xml = new DomDocument;
$xml->load('yourFile');
$xpath = new DomXpath($xml);

foreach ($xpath->query('//xml/opis[@lang="cz"]') as $rowNode) {
echo $rowNode->nodeValue; // will be 'this item'
}


Related Topics



Leave a reply



Submit