按属性值进行Xpath过滤,并选择备用属性


Xpath filter by attribute value and select alternate attribute

我在使用XPath查询时遇到了麻烦。我使用//link[@rel='alternate'],但这返回一个空节点集。我正试图编写一个查询,将选择所有链接节点的href属性的值,其中rel=alternate

我做错了什么?

下面是我正在使用的xml结构的简化示例。

<feed>
    <entry>
        <id>1980475</id>
        <link rel="post" href="http://..."></link>
        <link rel="edit" href="http://..."></link>
        <link rel="alternate" href="http://..."></link>
    </entry>
    <entry>
        <id>1980476</id>
        <link rel="post" href="http://..."></link>
        <link rel="edit" href="http://..."></link>
        <link rel="alternate" href="http://..."></link>
    </entry>
</feed>

下面是我使用的php代码:

$xmlDoc = simplexml_load_file("somefile.xml");
$nodelist = $xmlDoc->xpath("//link[@rel='alternate']");

正如@Jens所指出的,您可能正在处理一个Atom提要。Atom中的XML元素位于Atom名称空间中,其URI为http://www.w3.org/2005/Atom

您需要注册该名称空间并在XPath表达式中使用它。关于如何做到这一点,请看下面的答案。

当您发布输入XML的"简化样例"时,您可能删除了默认名称空间声明,如

所示
<feed xmlns="http://www.w3.org/2005/Atom">

这个看似无关重要的更改意味着<feed>及其派生的所有元素都不在名称空间中,而在实际输入数据中,它们位于Atom名称空间中。这就解释了为什么XPath表达式在测试样例输入(如@Passerby所说)时可以工作,而在实际输入上却不能工作。

如果将a注册为Atom名称空间的名称空间前缀,如我上面链接到的答案所示,那么XPath表达式将为:

xpath("//a:link[@rel='alternate']")