I have some XML like this:
<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-attribute>
</item>
How do I use xpath to find the custom-attribute
element than has an attribute-id of taco
?
How do I use xpath to find the custom-attribute
element(s) than have attribute-ids of htmlContent
? There are 2 in this case. Also these have namespaces on them. I'm not sure if that matters or not.
I have tried something like this:
var_dump($xml->xpath("custom-attribute[@attribute-id='taco']"));
But this doesn't work. I can iterate thru the custom-attribute
elements and look for what I need, but it would be a lot easier to simply select it via xpath
.
What am I missing here?
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