SimpleXML: Selecting Elements Which Have A Certain Attribute Value
Solution 1
Try this XPath:
/object/data[@type="me"]
Which reads as:
- Select (
/
) children of the current element calledobject
- Select (
/
) their children calleddata
- Filter (
[...]
) that list to elements where ...- the attribute
type
(the@
means "attribute") - has the text value
me
- the attribute
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".
Solution 2
I just made a function to do this for me; it only grabs the first result though. Your mileage may vary.
function query_attribute($xmlNode, $attr_name, $attr_value) {
foreach($xmlNode as $node) {
if($node[$attr_name] == $attr_value) {
return $node;
}
}
}
Usage:
echo query_attribute($MySimpleXmlNode->Customer, "type", "human")->Name;
(For the XML below)
<Root><Customer type="human"><Name>Sam Jones</name></Customer></Root>
Ar5hv1r
Software engineer at Waymo and Google, interested in Java language and library design as well as Rust, Bash, C++, code quality and testing. Contributor to Guava, Guice, and Truth. GitHub repos bkt: Subprocess caching CLI utility, written in Rust bash-cache: Caching / memoization utility for Bash ProfileGem: an extensible and modular way to control your Bash shell. prompt.gem: a clean, customizable prompt for your Bash shell. task-mon: Helper for pinging healthchecks.io F-ANSI: Java library for colored terminal output and cursor control via ANSI escape codes. b: Lightweight distributed issue tracker for Mercurial repositories. I release all my StackOverflow/StackExchange code snippets under an Apache license, in case StackExchange's CC-BY-SA is insufficient for your use case.
Updated on July 07, 2020Comments
-
Ar5hv1r almost 4 years
In an XML document, I have elements which share the same name, but the value of an attribute defines what type of data it is, and I want to select all of those elements which have a certain value from the document. Do I need to use XPath (and if so, could you suggest the right syntax) or is there a more elegant solution?
Here's some example XML:
<object> <data type="me">myname</data> <data type="you">yourname</data> <data type="me">myothername</data> </object>
And I want to select the contents of all
<data>
tags children of<object>
who's type isme
.PS - I'm trying to interface with the Netflix API using PHP - this shouldn't matter for my question, but if you want to suggest a good/better way to do so, I'm all ears.
-
Ar5hv1r almost 12 yearsWhy not use the XPath Gumbo suggested? And why use a switch instead of the easier to read
if($node[$attr_name] == $attr_value)
? -
IMSoP almost 4 yearsThis is a useful example to have, because sometimes you want to incorporate additional logic, so that XPath isn't the best approach.
-
Austin Burk almost 3 yearsCan this be done when the element has a default xmlns?