2

我需要一些帮助。我有这个 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 的 XY 值的数组。

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')

变量“材料”具有正确的内存地址,但我很难从 X 和 Y 中获取值。

谢谢。

拉斐尔

4

3 回答 3

1

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

    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")...]

于 2013-10-16T11:39:46.983 回答
1

在“材料”下方,您有两个级别 - 因此您需要通过两个级别才能找到所有。你可以这样做:

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 节点不存在,这将引发异常,您会立即看到它。

您需要进行另一个列表理解才能将它们转换为浮动,但您已经可以这样做了。

于 2013-10-16T13:13:54.923 回答
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)
于 2013-10-16T13:38:50.720 回答