使用XPATH返回多个节点属性

时间:2012-01-15 11:07:30

标签: xml xpath

我需要从XML获取数据,而我正在使用XPath,虽然我很喜欢它,但它很新。

我正在根据它们的属性检索一些节点:

/cesAlign/linkGrp[@targType='s']

现在我想获得节点中另一个属性的值:

/cesAlign/linkGrp[@targType='s']/@fromDoc

然而,这仅返回第一个命中。我想返回包含targType ='s'

的所有节点的属性

我在考虑循环遍历节点列表,然后读取属性......就像这样:

expr = xpath.compile("/cesAlign/linkGrp[@targType='s']/@fromDoc");
    NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

    int i = 0;
    for (i = 0; i < nl.getLength(); i++) {
        expr = xpath.compile("/@fromDoc");
        System.out.println((String) expr.evaluate(nl, XPathConstants.STRING));
    }

但我不确定是否有更好,更优雅的方法来做到这一点。

以下是XML示例:

<cesAlign version="1.0">
 <linkGrp targType="s" toDoc="mt/C2004310.01029701.xml.gz" fromDoc="en/C2004310.01029701.xml.gz">
 <linkGrp targType="s" toDoc="mt/C2004310.01029702.xml.gz" fromDoc="en/C2004310.01029702.xml.gz">
</cesAlign>

谢谢!

2 个答案:

答案 0 :(得分:1)

我认为你必须遍历找到的匹配并获取每个元素的属性值。使用"//cesAlign/linkGrp[@targType='s' and @fromDoc]"选择元素。 这是一个优雅的python解决方案:

#sample XML
xml = """
<cesAlign version="1.0">
 <linkGrp targType="s" toDoc="mt/C2004310.01029701.xml.gz" fromDoc="en/C2004310.01029701.xml.gz"/>
 <linkGrp targType="s" toDoc="mt/C2004310.01029702.xml.gz" fromDoc="en/C2004310.01029702.xml.gz"/>
 <linkGrp targType="s" toDoc="mt/C2004310.01029702.xml.gz" fromDoc="en/C2004310.01029703.xml.gz"/>
 <linkGrp targType="s" toDoc="mt/C2004310.01029702.xml.gz" fromDoc="en/C2004310.01029704.xml.gz"/>
 <linkGrp targType="s" toDoc="mt/C2004310.01029702.xml.gz" notFromDoc = "1"/>
 <linkGrp targType="s" toDoc="mt/C2004310.01029702.xml.gz" notFromDoc = "2"/>
</cesAlign>
"""
from lxml import etree
root = etree.fromstring(xml)
expr = root.xpath("//cesAlign/linkGrp[@targType='s' and @fromDoc]")
print "Matches:", len(expr)
for e in expr:
    print e.attrib["fromDoc"]

输出将是:

Matches: 4
en/C2004310.01029701.xml.gz
en/C2004310.01029702.xml.gz
en/C2004310.01029703.xml.gz
en/C2004310.01029704.xml.gz

答案 1 :(得分:0)

或者,您可以使用单独的XPath表达式获取每个所需属性:

/cesAlign/linkGrp[@targType='s'][$x]/@fromDoc 

其中$x必须用区间中的整数替换:

[1, count(/cesAlign/linkGrp[@targType='s'])]

如果您有可用的XPath 2.0引擎,可以使用单个XPath 2.0表达式获取所有所需属性的值

/cesAlign/linkGrp[@targType='s']/@fromDoc/string(.)

评估此XPath 2.0表达式时,结果是一个包含每个所需fromDoc属性的字符串值的序列。