8bitmagic
8bitmagic

Reputation: 27

XML namespaces - how to get them?

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

Answers (3)

ThW
ThW

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
    elements without a prefix
  • http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd
    element with prefix ns2

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

splash58
splash58

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'); 

demo

Or in this way

$ns = $sxe->getNamespaces(true);
$sxe->registerXPathNamespace('ns2',$ns['ns2']);
$result=$sxe->xpath('//ns2:title');

demo

Upvotes: 0

Ognj3n
Ognj3n

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

Related Questions