Reputation: 11
I have tried almost everything but i cannot seem to read the namespaced "m:inline" element and the "feed" and "title" children from the following SimpleXMLElement dump:
SimpleXMLElement {#235
+"@attributes": array:4 [
"rel" => "http://schemas.microsoft.com/ado/2007/08/dataservices/related/test"
"type" => "application/atom+xml;type=feed"
"title" => "some title"
"href" => "JobRequisition(23453453L)/Test"
]
+"m:inline": SimpleXMLElement {#152
+"feed": SimpleXMLElement {#123
+"title": "jobReqLocale"
...some more data ahead skipped here
The raw xml start:
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/jobReqLocale" type="application/atom+xml;type=feed" title="some title" href="JobRequisition(23453453L)/Test">
<m:inline>
<feed>
<title type="text">jobReqLocale</title>
...
I have tried:
$simpleXmlElement = new SimpleXMLElement($xml, LIBXML_NOERROR, false);
dd($simpleXmlElement->children('m', true)->feed);
The result is always an empty SimpleXmlElement
with all kinds of variations including xpath. Am i doing something wrong? Is SimpleXML not supporting these kinds of structures?
Upvotes: 1
Views: 881
Reputation: 97783
Your document contains (at least) two namespaces: one with the local prefix m
, and one with no prefix (the "default namespace"). It may actually contain other namespaces you haven't shown, or re-assign both the m:
prefix and the default namespace at different points in the document, but within the fragment you've shown:
inline
element is in the namespace with local prefix m
link
, feed
, and title
elements are in the default namespaceAs discussed on "Reference - how do I handle namespaces (tags and attributes with colon in) in SimpleXML?" the ->children()
method switches namespaces, so:
inline
element, you would use ->children('m', true)->inline
feed
element inside it, you need to switch back to the default namespace, with ->children(null, true)->feed
title
element inside that, you will already be in the default namespace, so can just use ->title
type
attribute can be accessed directly with ['type']
To summarise:
$type = (string)$simpleXmlElement
->children('m', true)
->inline
->children(null, true)
->feed
->title
['type'];
Note that ideally you'd hard-code the namespace URIs, which are not subject to change, rather than the prefixes. You could also avoid assuming which is the default namespace and explicitly select the null namespace when selecting attributes. That would give you something more like this:
$type = (string)$simpleXmlElement
->children(XMLNS_SOMETHING)
->inline
->children(XMLNS_OTHER_THING)
->feed
->title
->attributes(null)
->type;
Upvotes: 1