I want to extract some data from xml.
I have this xml:
<root>
<p>Some text</p>
<p>Even more text</p>
<span class="bla bla">
<span class="currency">EUR</span> 19.95
</span>
</root>
and then I run this php code
$xml = simplexml_load_string($xmlString);
$json = json_encode($xml);
$obj = json_decode($json);
print_r($obj);
and the result is:
stdClass Object
(
[p] => Array
(
[0] => Some text
[1] => Even more text
)
[span] => stdClass Object
(
[@attributes] => stdClass Object
(
[class] => bla bla
)
[span] => EUR
)
)
How do I get the missing string "19.95"?
Don't convert XML into JSON/an array. It means that you loose information and features.
SimpleXML is litmit, it works with basic XML, but it has problems with thing like mixed nodes. DOM allows for an easier handling in this case.
$xml = <<<'XML'
<root>
<p>Some text</p>
<p>Even more text</p>
<span class="bla bla">
<span class="currency">EUR</span> 19.95
</span>
</root>
XML;
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
foreach($xpath->evaluate('/root/span[@class="bla bla"]') as $span) {
var_dump(
$xpath->evaluate('string(span[@class="currency"][1])', $span),
$xpath->evaluate(
'number(span[@class="currency"][1]/following-sibling::text()[1])',
$span
)
);
}
Xpath is an expression language to fetch parts of an DOM (Think SQL for XML). PHP has several method to access it. SimpleXMLElement::xpath()
allows to fetch nodes as arrays of SimpleXMLElement objects. DOMXpath::query()
allows you to fetch node lists. Only DOMXpath::evaluate()
allows to fetch node lists and scalar values.
In the example /root/span[@class="bla bla"]
fetches all span
element nodes that have the given class attribute. For each of the nodes it then fetches the span
with the class currency as a string. The third expression fetches the first following sibling text node of the currency
span as a number.