XPath 查询返回“false”在简单 XML 中

发布于 2024-08-28 11:02:01 字数 2674 浏览 8 评论 0原文

我有一个这样的 xml 片段:

<meta_tree type="root">
    <meta_data>
        <meta_cat>Content Provider</meta_cat>
        <data>Mammoth</data>
    </meta_data>
    <meta_data>
        <meta_cat>Genre</meta_cat>
        <data>Games</data>
    </meta_data>
    <meta_data>
        <meta_cat>Channel Name</meta_cat>
        <data>Games Trailers</data>
    </meta_data>
    <meta_data>
        <meta_cat>Collection</meta_cat>
        <data>Strategy</data>
    </meta_data>
    <meta_data>
        <meta_cat>Custom 1</meta_cat>
        <data>PC</data>
    </meta_data>
    <meta_data>
        <meta_cat>DRM Protected</meta_cat>
        <data>N</data>
    </meta_data>
    <meta_data>
        <meta_cat>Aspect Ratio</meta_cat>
        <data>16:9</data>
    </meta_data>
    <meta_data>
        <meta_cat>Streaming Type</meta_cat> 
        <data>VOD</data>
    </meta_data>
</meta_tree>

它是从 $meta_tree->asXML() 的片段中获取的。

鉴于此,我需要对每个元素进行 xpath 查询,因此我使用:

$meta_tree->xpath("/meta_data[meta_cat='Content Provider']");

但这返回 false。

我尝试过:

  • /meta_tree/meta_data[meta_cat='Content Provider']
  • //meta_data[meta_cat='Content Provider']
  • meta_data[meta_cat='Content Provider'] (这会返回一个数组,但该数组为空)

我一直在使用 AquaPath,它验证了我的查询,所以我不确定我做错了什么。

有人有什么想法吗?

DJ。

编辑:根据托洛马克的建议,这里有一些更多信息。

该元素是较大文档的片段,如下所示(名称已替换为 *** 以保护无辜者):

<contents total_items="1" xmlns="http://rxml.***.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://rxml.***.com/xsd/*Ingestion.xsd ">
     <content item_id="451195">
         ...
         <meta_tree type="root">
             ... see snippet above ...
         </meta_tree>
    </content>
</contents>

我通过以下方式检索上面的片段:

$dom = new SimpleXMLElement(... xml_string ... );
foreach($dom->content as $content)
{
    $contentMetadata = $this->getMetadata($content->meta_tree)
}

public function getMetadata($meta_tree)
{
    echo $meta_tree->asXML();
}

答案: 问题是默认名称空间。我选择将它们删除而不是处理名称空间,除非有人知道如何在 SimpleXMLElement 中注册 xmlns 默认名称空间。

I have an xml fragment as such:

<meta_tree type="root">
    <meta_data>
        <meta_cat>Content Provider</meta_cat>
        <data>Mammoth</data>
    </meta_data>
    <meta_data>
        <meta_cat>Genre</meta_cat>
        <data>Games</data>
    </meta_data>
    <meta_data>
        <meta_cat>Channel Name</meta_cat>
        <data>Games Trailers</data>
    </meta_data>
    <meta_data>
        <meta_cat>Collection</meta_cat>
        <data>Strategy</data>
    </meta_data>
    <meta_data>
        <meta_cat>Custom 1</meta_cat>
        <data>PC</data>
    </meta_data>
    <meta_data>
        <meta_cat>DRM Protected</meta_cat>
        <data>N</data>
    </meta_data>
    <meta_data>
        <meta_cat>Aspect Ratio</meta_cat>
        <data>16:9</data>
    </meta_data>
    <meta_data>
        <meta_cat>Streaming Type</meta_cat> 
        <data>VOD</data>
    </meta_data>
</meta_tree>

which I garnered from the snippet of $meta_tree->asXML().

So given that, I need to have an xpath query for each element, so I'm using:

$meta_tree->xpath("/meta_data[meta_cat='Content Provider']");

but this returns false.

I have tried:

  • /meta_tree/meta_data[meta_cat='Content Provider']
  • //meta_data[meta_cat='Content Provider']
  • meta_data[meta_cat='Content Provider'] (this returns an array, but the array is empty)

I've been using AquaPath, which validates my query, so I'm not sure what I'm doing wrong.

Anyone got any ideas?

DJS.

EDIT: As per Tolomak's suggestion, here's some more info.

The element is a fragment of a larger doc, as follows (names have been replaced with *** to protect the innocent):

<contents total_items="1" xmlns="http://rxml.***.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://rxml.***.com/xsd/*Ingestion.xsd ">
     <content item_id="451195">
         ...
         <meta_tree type="root">
             ... see snippet above ...
         </meta_tree>
    </content>
</contents>

I retrieve the fragment above by:

$dom = new SimpleXMLElement(... xml_string ... );
foreach($dom->content as $content)
{
    $contentMetadata = $this->getMetadata($content->meta_tree)
}

public function getMetadata($meta_tree)
{
    echo $meta_tree->asXML();
}

ANSWER: problem was the default namespace. I have chosen to strip them out rather than deal with the namespace, unless anyone knows how to register the xmlns default namespace in SimpleXMLElement.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随心而道 2024-09-04 11:02:01

尝试

$meta_tree->xpath("meta_data[meta_cat='Content Provider']")

例如

<?php
$meta_tree = new SimpleXMLElement(getData());
$foo = $meta_tree->xpath("meta_data[meta_cat='Content Provider']");
var_dump($foo);

function getData() {
  return '<meta_tree type="root">
    <meta_data>
        <meta_cat>Content Provider</meta_cat>
        <data>Mammoth</data>
    </meta_data>
    <meta_data>
        <meta_cat>Genre</meta_cat>
        <data>Games</data>
    </meta_data>
    <meta_data>
        <meta_cat>Channel Name</meta_cat>
        <data>Games Trailers</data>
    </meta_data>
    <meta_data>
        <meta_cat>Collection</meta_cat>
        <data>Strategy</data>
    </meta_data>
    <meta_data>
        <meta_cat>Custom 1</meta_cat>
        <data>PC</data>
    </meta_data>
    <meta_data>
        <meta_cat>DRM Protected</meta_cat>
        <data>N</data>
    </meta_data>
    <meta_data>
        <meta_cat>Aspect Ratio</meta_cat>
        <data>16:9</data>
    </meta_data>
    <meta_data>
        <meta_cat>Streaming Type</meta_cat> 
        <data>VOD</data>
    </meta_data>
  </meta_tree>';
}

印刷

array(1) {
  [0]=>
  object(SimpleXMLElement)#2 (2) {
    ["meta_cat"]=>
    string(16) "Content Provider"
    ["data"]=>
    string(7) "Mammoth"
  }
}

try

$meta_tree->xpath("meta_data[meta_cat='Content Provider']")

e.g.

<?php
$meta_tree = new SimpleXMLElement(getData());
$foo = $meta_tree->xpath("meta_data[meta_cat='Content Provider']");
var_dump($foo);

function getData() {
  return '<meta_tree type="root">
    <meta_data>
        <meta_cat>Content Provider</meta_cat>
        <data>Mammoth</data>
    </meta_data>
    <meta_data>
        <meta_cat>Genre</meta_cat>
        <data>Games</data>
    </meta_data>
    <meta_data>
        <meta_cat>Channel Name</meta_cat>
        <data>Games Trailers</data>
    </meta_data>
    <meta_data>
        <meta_cat>Collection</meta_cat>
        <data>Strategy</data>
    </meta_data>
    <meta_data>
        <meta_cat>Custom 1</meta_cat>
        <data>PC</data>
    </meta_data>
    <meta_data>
        <meta_cat>DRM Protected</meta_cat>
        <data>N</data>
    </meta_data>
    <meta_data>
        <meta_cat>Aspect Ratio</meta_cat>
        <data>16:9</data>
    </meta_data>
    <meta_data>
        <meta_cat>Streaming Type</meta_cat> 
        <data>VOD</data>
    </meta_data>
  </meta_tree>';
}

prints

array(1) {
  [0]=>
  object(SimpleXMLElement)#2 (2) {
    ["meta_cat"]=>
    string(16) "Content Provider"
    ["data"]=>
    string(7) "Mammoth"
  }
}
罗罗贝儿 2024-09-04 11:02:01

问题是默认的命名空间。我选择将它们删除而不是处理名称空间,除非有人知道如何在 SimpleXMLElement 中注册 xmlns 默认名称空间。

Problem was the default namespace. I have chosen to strip them out rather than deal with the namespace, unless anyone knows how to register the xmlns default namespace in SimpleXMLElement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文