1

I'm having some issues retrieving the tag values of an XML feed which has a namespace.

I've read and tried to implement some of the recommended answers on previous questions, but I still get an empty array, or a warning like

Warning: SimpleXMLElement::xpath() [simplexmlelement.xpath]: Undefined namespace prefix

I read Parse XML with Namespace using SimpleXML.

The XML feed data looks like this:

<Session>
      <AreComplimentariesAllowed>true</AreComplimentariesAllowed>
      <Attributes xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
         <d3p1:string>0000000009</d3p1:string>
         <d3p1:string>0000000011</d3p1:string>
      </Attributes>
</Session>

My current code:

foreach($xml->Session as $event){
    if(!empty($event->Attributes)){
        foreach($event->xpath('//Attributes:d3p1') as $atts) {
             echo $atts."<br />";
        }
    }
}

Any guidance would be appreciated.

Thanks.

Community
  • 1
  • 1
David
  • 369
  • 2
  • 4
  • 14

1 Answers1

1

You need to register the namespace:

foreach ($xml->xpath('//Attributes') as $attr) {
  $attr->registerXPathNamespace('ns',
    'http://schemas.microsoft.com/2003/10/Serialization/Arrays');
  foreach ($attr->xpath('//ns:string') as $string) {
    echo $string, PHP_EOL;
  }
}

In case if you want to fetch only the values of string tags:

$xml->registerXPathNamespace('ns',
  'http://schemas.microsoft.com/2003/10/Serialization/Arrays');
foreach ($xml->xpath('//Attributes/ns:string') as $string) {
  echo $string, PHP_EOL;
}
Ruslan Osmanov
  • 20,486
  • 7
  • 46
  • 60
  • Thanks for these. Non of them worked, but would that be because the link in the namespace is now dead? http://schemas.microsoft.com/2003/10/Serialization/Arrays – David Nov 21 '16 at 16:42
  • @David, actually both of the samples work, if you load the `$xml` properly. [Example](https://eval.in/682071) – Ruslan Osmanov Nov 21 '16 at 16:45
  • Initially I use cURL to get the data as XML (curl_setopt($ch, CURLOPT_HTTPHEADER,array('Accept: application/xml') and then load using: $xml = new SimpleXMLElement(str_replace("&", "&", $data)); – David Nov 21 '16 at 17:02
  • I have accepted your answer though, as you've proven that it works and my issue is different to my original question. – David Nov 21 '16 at 17:08
  • Namespaces do not have to be existing URLs, only valid URNs. You might have a namespace on the outer XML that does not use an prefix. (Look for an `xmlns="..."` attribute.) – ThW Nov 21 '16 at 18:09
  • Ah, Ok.. that may make more sense. There is an outer element: ` true 0000000009 0000000011 ` – David Nov 22 '16 at 09:08