Reputation: 27
Been trying to extract some XML with namespaces in it. I've tried to understand this myself; but I can't seem to identify exactly whats wrong with what I'm doing.
I have this set to variable $myXMLData
, and running the following code to spit out the title attribute:
$myXMLData=<<<XML
<getmatchingproductresponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<getmatchingproductresult asin="055726328X" status="Success">
<product>
<attributesets>
<ns2:itemattributes xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd" xml:lang="en-US">
<ns2:studio>lulu.com</ns2:studio>
<ns2:title>You Are a Spiritual Healer</ns2:title>
</ns2:itemattributes>
</attributesets>
<relationships>
</relationships>
</product>
</getmatchingproductresult>
<responsemetadata>
<requestid>4304bf06-acd2-4792-804a-394a2e01656f</requestid>
</responsemetadata>
</getmatchingproductresponse>
XML;
$sxe=new SimpleXMLElement($myXMLData);
$sxe->registerXPathNamespace('ns','http://mws.amazonservices.com/schema/Products/2011-10-01');
$result=$sxe->xpath('//ns:title');
foreach ($result as $title)
{
echo $title . "<br>";
}
But my output is blank. What am I doing wrong here? Please help...!
Upvotes: 2
Views: 267
Reputation: 19492
You did register the wrong namespace in the nopaste. Here are two namespaces in the document.
http://mws.amazonservices.com/schema/Products/2011-10-01
http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd
The title
uses the prefix ns2
. You don't have to register the prefixes used in the document. You can and should just register you own. In SimpleXML you will have to do that on any element you like to call the method xpath() on. It helps creating a small function for it.
$xmlns = [
'p' => 'http://mws.amazonservices.com/schema/Products/2011-10-01',
'pd' => 'http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd'
];
function registerNamespacesOnElement(
SimpleXMLElement $element, array $namespaces
) {
foreach ($namespaces as $prefix => $namespace) {
$element->registerXpathNamespace($prefix, $namespace);
}
}
$sxe=new SimpleXMLElement($xml);
registerNamespacesOnElement($sxe, $xmlns);
$result=$sxe->xpath('//pd:title');
foreach ($result as $title) {
echo $title . "<br>\n";
}
Output:
You Are a Spiritual Healer<br>
Upvotes: 2
Reputation: 26153
// Register namespace, set in xml declaration
$sxe->registerXPathNamespace('ns2','http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd');
// And use the same prefix as in xml
$result=$sxe->xpath('//ns2:title');
Or in this way
$ns = $sxe->getNamespaces(true);
$sxe->registerXPathNamespace('ns2',$ns['ns2']);
$result=$sxe->xpath('//ns2:title');
Upvotes: 0
Reputation: 759
Have you set your header to be text/xml
? By default PHP sets the Content-Type to to text/html, so browser tries to display your XML like it is HTML. That's why you probably get blank result.
Try adding this:
header('Content-Type: text/xml');
Upvotes: 0