【问题标题】:SimpleXml with namespace issues具有命名空间问题的 SimpleXml
【发布时间】:2018-06-04 10:03:54
【问题描述】:

我几乎尝试了所有方法,但我似乎无法从以下 SimpleXMLElement 转储中读取命名空间的“m:inline”元素以及“feed”和“title”子元素:

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 不支持这些类型的结构吗?

【问题讨论】:

  • 请您 edit 包含您尝试解析的 XML 示例,而不是任何调试输出? SimpleXML 在大多数通用调试中往往显示不佳,因为它没有“真正的”属性。
  • 我已经添加了xml文件的开头。

标签: php xml simplexml


【解决方案1】:

您的文档包含(至少)两个命名空间:一个带有本地前缀 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?”中所讨论的,-&gt;children() 方法切换命名空间,所以:

  • 要选择inline 元素,您可以使用-&gt;children('m', true)-&gt;inline
  • 要选择其中的feed 元素,您需要将back 切换到默认命名空间,使用-&gt;children(null, true)-&gt;feed
  • 要访问其中的title 元素,您已经在默认命名空间中,因此可以使用-&gt;title
  • 在这种特殊情况下,您是在默认命名空间还是“无命名空间”中都没有关系,因此可以使用['type'] 直接访问type 属性
  • 记得将任何属性或元素转换为字符串以获取其字符串内容

总结一下:

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

请注意,理想情况下,您应该硬编码命名空间 URI,而不是前缀,它们不会更改。您还可以避免假设哪个是默认命名空间,并在选择属性时显式选择 null 命名空间。这会给你更多类似的东西:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2016-05-14
    相关资源
    最近更新 更多