SimpleXML:选择具有特定属性值的元素

36
在一个XML文档中,我有一些元素它们具有相同的名称,但属性的值定义了它是什么类型的数据,我想从文档中选择所有具有特定值的元素。我需要使用XPath(如果需要,可以建议正确的语法),还是有更简便的解决方法?
以下是一些示例XML:
<object>
  <data type="me">myname</data>
  <data type="you">yourname</data>
  <data type="me">myothername</data>
</object>

我想选择所有类型为me<object>标签下的所有<data>标签的内容。

PS- 我正在使用PHP接口Netflix API,这对我的问题不重要,但如果您有建议一个更好的方法,我很乐意听取。


交叉引用:在XPath中实现条件 - hakre
2个回答

54

尝试使用这个XPath:

/object/data[@type="me"]
  • 选择当前元素下名为object的子元素 (/)
  • 选择它们名为data的子元素 (/)
  • 筛选([...])列表中满足以下条件的元素:
    • type属性的文本值(@表示属性)
    • me

因此:

$myDataObjects = $simplexml->xpath('/object/data[@type="me"]');
如果object不是您文档的根元素,则您可能希望使用//object/data[@type="me"]。其中,//表示“查找所有后代”,而不是“查找所有子元素”。

当元素具有默认的 xmlns 时,这是否可以完成? - Austin Burk

5

我刚刚编写了一个函数来为我完成这个操作;但是它只获取第一个结果。您的结果可能会有所不同。

function query_attribute($xmlNode, $attr_name, $attr_value) {
  foreach($xmlNode as $node) { 
    if($node[$attr_name] == $attr_value) {
        return $node;
    }
  }
}

使用方法:

echo query_attribute($MySimpleXmlNode->Customer, "type", "human")->Name;

(对于以下XML)

(下面的XML)

<Root><Customer type="human"><Name>Sam Jones</name></Customer></Root>

11
为什么不使用Gumbo建议的XPath呢?而且为什么要使用switch语句,而不是更易于阅读的if($node[$attr_name] == $attr_value) - dimo414
这是一个有用的示例,因为有时您想要加入额外的逻辑,这样XPath并不是最好的方法。 - IMSoP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接