在xml中找到特定的子项

时间:2018-06-18 15:13:24

标签: python xml indexing attributes

<graphiceditor>
    <plot name="DS_Autobahn 1.Track: Curvature &lt;78.4204 km>" type="CurvePlot">
        <parent>DS_Autobahn 1</parent>
        ...
        <curve name="" isXTopAxis="0" markerSize="8" symbol="-1" 
            <point x="19.986891478960015" y="-0.00020825890723451596"/>
            <point ....

您好,我想打开.xml文件,找到&#34;曲线&#34;并将曲线的y坐标导入列表。我知道&#34;曲线&#34;有索引[16]所以我现在正在使用它:

tree = ET.parse(file_name)
root = tree.getroot()    
curvature = [float(i) for i in[x["y"] for x in [root[0][16][i].attrib for i in range(len(root[0][16]))]]]

但是,如果曲线不在第16位,我该怎么办呢?如何在任何xml文件中找到曲线呢?我现在已经尝试了几个小时,但我根本就没有得到它。非常感谢你提前。

3 个答案:

答案 0 :(得分:0)

例如,您可以使用XPath。

这基本上就像:

root.findall(xpath)

你的xpath将是&#39; .// curve&#39;如果你只对标签型曲线的所有孩子感兴趣。

有关xpath的更多信息,请参阅w3schools

答案 1 :(得分:0)

我建议学习正则表达式(通常称为正则表达式),我会一直使用它们来解决这类问题。

这是参考正则表达式的不同方面的好地方: Regex

正则表达式是一种匹配文本的方式,它与if "substring" in string:非常相似,除了强大一百倍之外。正则表达式的全部目的是找到“子串”,即使你不知道它是什么。

因此,让我们仔细研究一下您的示例,首先要做的是确切地确定哪些规则必须为真才能“匹配”y值。 我不知道你究竟是如何阅读你的数据,但我正在将它作为单个字符串阅读。

string = '<graphiceditor>' \
    '<plot name="DS_Autobahn 1.Track: Curvature &lt;78.4204 km>" type="CurvePlot">' \
    '<parent>DS_Autobahn 1</parent>' \
    '<curve name="" isXTopAxis="0" markerSize="8" symbol="-1"' \
    '<point x="19.986891478960015" y="-0.00020825890723451596"/>' \
    '<point ....'

你可以看到我将sting分成多行以使其更具可读性。如果你是从open()的文件中读取它,请确保删除“\ n”元字符或我的正则表达式不会工作(不是你不能写正则表达式!)

我想要做的第一件事是找到曲线标签,然后我想继续找到y =部分,然后只抓住数字。让我们将其简化为真正定义的步骤:

  1. 查找曲线部分的开始位置
  2. 继续,直到下一个y =部分开始
  3. 在y = section之后从引号内获取值。
  4. 现在对于正则表达式,我可以解释它究竟是如何工作的,但我们整天都在这里。回到我在开始和阅读时链接的Doc。

    import re
    string = "[see above]"
    y_val = re.search('<curve.*?y="(.*?)"', string).group(1)
    

    就是这样!将你的y_val转换为float(),你准备好了!

答案 2 :(得分:0)

Use an XML parser to parse XML; not regex.

如在另一个答案中提到的那样,我也会使用XPath。如果您需要使用复杂的XPath,我建议使用lxml。在你的例子中,虽然ElementTree就足够了。

例如,这个Python ......

import xml.etree.ElementTree as ET

tree = ET.parse("file_name.xml")
root = tree.getroot()
curvature = [float(y) for y in [point.attrib["y"] for point in root.findall(".//curve/point[@y]")]]

print(curvature)

使用此XML(&#34; file_name.xml&#34;)...

<graphiceditor>
    <plot name="DS_Autobahn 1.Track: Curvature &lt;78.4204 km>" type="CurvePlot">
        <parent>DS_Autobahn 1</parent>
        <curve name="" isXTopAxis="0" markerSize="8" symbol="-1">
            <point x="19.986891478960015" y="-0.00020825890723451596"/>
            <point x="19.986891478960015" y="-0.00030825690983451678"/>
        </curve>
    </plot>
</graphiceditor>

将打印...

[-0.00020825890723451596, -0.0003082569098345168]

注意:请注意列表中第二个y坐标与XML中的内容之间的区别。这是因为您将值转换为浮动值。如果需要保持精度,请考虑转换为小数。