带名称空间问题的SimpleXml

时间:2018-06-04 10:03:55

标签: php xml simplexml

我几乎尝试了所有东西,但我似乎无法阅读命名空间" m:inline"元素和"饲料"和"标题"来自以下SimpleXMLElement转储的子项:

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

原始xml开始:

<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>

...

我试过了:

$simpleXmlElement = new SimpleXMLElement($xml, LIBXML_NOERROR, false);

dd($simpleXmlElement->children('m', true)->feed);

结果总是一个空的SimpleXmlElement

包括xpath在内的各种变化。难道我做错了什么? SimpleXML不支持这些结构吗?

1 个答案:

答案 0 :(得分:0)

您的文档包含(至少)两个名称空间:一个具有本地前缀m,另一个没有前缀(“默认名称空间”)。它实际上可能包含您未显示的其他命名空间,或者在文档中的不同点重新分配m:前缀和默认命名空间,但是在您显示的片段中

  • inline元素位于具有本地前缀m
  • 的命名空间中
  • linkfeedtitle元素位于默认命名空间
  • 各种属性are in no namespace at all;特别是,这与它们在默认命名空间中的不同。

如“Reference - how do I handle namespaces (tags and attributes with colon in) in SimpleXML?”所述,->children()方法切换名称空间,所以:

  • 要选择inline元素,您可以使用->children('m', true)->inline
  • 要选择其中的feed元素,您需要将返回切换到默认命名空间,并使用->children(null, true)->feed
  • 要访问其中的title元素,您将已进入默认命名空间,因此可以使用->title
  • 在这种特殊情况下,如果您处于默认命名空间或“无命名空间”,则无关紧要,因此可以使用type
  • 直接访问['type']属性
  • 请记住将任何属性或元素强制转换为字符串以获取其字符串内容

总结:

$type = (string)$simpleXmlElement
    ->children('m', true)
            ->inline
    ->children(null, true)
            ->feed
            ->title
            ['type'];

请注意,理想情况下,您需要对名称空间URI进行硬编码,而URI名称不会更改,而不是前缀。您还可以避免假设哪个是默认命名空间,并在选择属性时显式选择空命名空间。这会给你更多这样的东西:

$type = (string)$simpleXmlElement
    ->children(XMLNS_SOMETHING)
            ->inline
    ->children(XMLNS_OTHER_THING)
            ->feed
            ->title
    ->attributes(null)
            ->type;