如何从xml文件中获取python值

时间:2013-10-16 11:32:08

标签: python xml elementtree

我需要一些帮助。我有这个XML:

<?xml version="1.0"?>
<WDAT>
<EMOD>
      <MATERIAL number="1.2345">
            <Values>
                      <X>20.0</X>
                      <Y>200.0</Y>
            </Values>
            <Values>
                      <X>100.0</X>
                      <Y>190.0</Y>
            </Values>
            <Values>
                      <X>200.0</X>
                      <Y>185.0</Y>
            </Values>
            <Values>
                      <X>300.0</X>
                      <Y>180.0</Y>
            </Values>
            <Values>
                      <X>400.0</X>
                      <Y>175.0</Y>
            </Values>
    </MATERIAL>
</EMOD>
</WDAT>

例如,我想获得一个物料编号为1.2345的X-Y值的数组。

tree_materials = ET.parse(r"materials.xml")
root_materials = tree_materials.getroot()
materials = root_materials.findall('EMOD/MATERIAL')
material = tree_materials.findall(".//MATERIAL[@number='1.2345']")
valuess = material.findall('X')

变量&#34;材料&#34;有正确的内存地址,但我很难从X和Y获取值。

感谢。

圣拉斐尔

3 个答案:

答案 0 :(得分:1)

在最后两行中,您可以执行以下操作:

    material = tree_materials.find(".//MATERIAL[@number='1.2345']")
    xs = material.findall('X')
    ys = material.findall('Y')
    values = zip([x.text for x in xs], [x.text for x in xs])

这将输出像[(“20.0”,“200.0”)...]

这样的元组列表

答案 1 :(得分:1)

在'MATERIAL'下面,你有两个级别 - 所以你需要将两个级别都传递给findall。你可以这样做:

material = tree_materials.find(".//MATERIAL[@number='1.2345']")
lx = material.findall('Values/X')
ly = material.findall('Values/Y')
points = zip([x.text for x in lx], [y.text for y in ly])

但是,你真的必须相信你的XML才能做到这一点 - 如果有人不小心给你这样的文件:

        <Values>
                  <X>200.0</X>
                  <Y>185.0</Y>
        </Values>
        <Values>
                  <Y>180.0</Y>
        </Values>
        <Values>
                  <X>400.0</X>
                  <Y>175.0</Y>
        </Values>

然后你会以(200.0, 185.0), (180.0, 175.0)结束,因为zip停在最短的项目上,400.0会被静静地删除,你甚至可能都不知道。 明确更好:

values = material.findall('Values')
points = [(v.find('X').text, v.find('Y').text) for v in values]

如果不存在X或Y节点,则会抛出异常,您将立即看到它。

你需要做另一个列表理解来将它们转换为浮动,但你已经可以做到了。

答案 2 :(得分:0)

material = tree_materials.xpath("//MATERIAL[@number='1.2345']")[0]
x_values = [x.text for x in material.xpath("//X")]
y_values = [y.text for y in material.xpath("//Y")]
xy_values = zip(x_values, y_values)