Python 解析和修改 XML 个元素和子元素

Python parse and modify XML elements and subelements

我正在使用 ElementTree 来解析和修改我的 XML-File,其结构如下。实际文件要大得多 Platz_1 到 Platz_250 但结构是一样的。现在我想立即将 Platz_X 的所有 elements.text 和 subelements.text 设置为“0”,当 Platz_X 的“_Name”的 element.text 是 None 并继续下一个 Platz_X+1

我的问题是当我循环解析文件以检查所有值时,我不知道如何停止循环将所有文本设置为“0”并继续下一个 Platz_X+1.


tree = ET.parse(xml)
root = tree.getroot()
wkz = root.getchildren()

for sub_wkz in wkz:
   for platz in sub_wkz:
      for child in platz:
        if child.text:
           if len(child.text.split()) > 0:
              var = child.text

        for subchild in child:
           if subchild.text:
              if len(child.text.split()) > 0:
                 var_sub = subchild.text
<?xml version='1.0' encoding='utf-8'?>
<Maschine>
  <INDUSTRIE_WKZ_1>
    <Platz_1>
      <_Name>6006003</_Name>
      <_Duplo>1</_Duplo>
      <_Zustand>131</_Zustand>
      <Schneide_1>
        <_Sollstandzeit>60,0</_Sollstandzeit>
        <_Iststandzeit>50,58213424682617</_Iststandzeit>
        <_Vorwarngrenze>10,0</_Vorwarngrenze>
        <_Laenge_L1>237,89599609375</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_1>
      <Schneide_2>
        <_Sollstandzeit>0</_Sollstandzeit>
        <_Iststandzeit>0</_Iststandzeit>
        <_Vorwarngrenze>0</_Vorwarngrenze>
        <_Laenge_L1>0</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_2>
      <Schneide_3>
        <_Sollstandzeit>0</_Sollstandzeit>
        <_Iststandzeit>0</_Iststandzeit>
        <_Vorwarngrenze>0</_Vorwarngrenze>
        <_Laenge_L1>0</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_3>
      <Schneide_4>
        <_Sollstandzeit>0</_Sollstandzeit>
        <_Iststandzeit>0</_Iststandzeit>
        <_Vorwarngrenze>0</_Vorwarngrenze>
        <_Laenge_L1>0</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_4>
    </Platz_1>
  <INDUSTRIE_WKZ_1>
<Maschine>

我稍微修改了你提供的 XML :

  • 将缺少的斜杠 (/) 添加到 INDUSTRIE_WKZ_1 结束标记
  • 将缺少的斜杠 (/) 添加到 <Maschine> 结束标记
  • 为简洁起见删除了 Schneide_2 到 4(但它可以正常工作)
  • INDUSTRIE_WKZ_2 中添加了一个 Platz_2,其 _Name 为空(如果这就是你所说的“是 None”的意思)(因此代码可以工作,如果有多个"WKZ")

这是我使用的输入文件:

<?xml version='1.0' encoding='utf-8'?>
<Maschine>
  <INDUSTRIE_WKZ_1>
    <Platz_1>
      <_Name>6006003</_Name>
      <_Duplo>1</_Duplo>
      <_Zustand>131</_Zustand>
      <Schneide_1>
        <_Sollstandzeit>60,0</_Sollstandzeit>
        <_Iststandzeit>50,58213424682617</_Iststandzeit>
        <_Vorwarngrenze>10,0</_Vorwarngrenze>
        <_Laenge_L1>237,89599609375</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_1>
    </Platz_1>
  </INDUSTRIE_WKZ_1>
  <INDUSTRIE_WKZ_2>
    <Platz_2>
      <_Name></_Name>
      <_Duplo>1</_Duplo>
      <_Zustand>131</_Zustand>
      <Schneide_1>
        <_Sollstandzeit>60,0</_Sollstandzeit>
        <_Iststandzeit>50,58213424682617</_Iststandzeit>
        <_Vorwarngrenze>10,0</_Vorwarngrenze>
        <_Laenge_L1>237,89599609375</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_1>
    </Platz_2>
  </INDUSTRIE_WKZ_2>
</Maschine>

我假设只有一个 Maschine 并且它只包含 INDUSTRIE_WKZ_* 其中包含 Platz_*.

这是我的代码:

from itertools import islice
from xml.etree.ElementTree import ElementTree as ET

src_xmlfile_name = "68253543.xml"
dst_xmlfile_name = "68253543_post.xml"

ET = ET()
root = ET.parse(src_xmlfile_name)
for platz_elem in root.findall("*/*"):  # all "Platz" children of "WKZ" children of the root
    platz_name_elem = platz_elem.find("_Name")
    if platz_name_elem.text is None:
        # we want to put to 0 all values in this Platz's descendants
        for platz_descendant in islice(platz_elem.iter(), 1, None):  # skip the first one, which is the "Platz" elem
            if (platz_descendant.tag != "_Name"  # keep "_Name
                    and platz_descendant.text is not None  # keep empty ones
                    and platz_descendant.text.strip() != ""):  #
                platz_descendant.text = "0"
ET.write(dst_xmlfile_name, encoding="utf-8", xml_declaration=True)

产生此输出:

<?xml version='1.0' encoding='utf-8'?>
<Maschine>
  <INDUSTRIE_WKZ_1>
    <Platz_1>
      <_Name>6006003</_Name>
      <_Duplo>1</_Duplo>
      <_Zustand>131</_Zustand>
      <Schneide_1>
        <_Sollstandzeit>60,0</_Sollstandzeit>
        <_Iststandzeit>50,58213424682617</_Iststandzeit>
        <_Vorwarngrenze>10,0</_Vorwarngrenze>
        <_Laenge_L1>237,89599609375</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_1>
    </Platz_1>
  </INDUSTRIE_WKZ_1>
  <INDUSTRIE_WKZ_2>
    <Platz_2>
      <_Name />
      <_Duplo>0</_Duplo>
      <_Zustand>0</_Zustand>
      <Schneide_1>
        <_Sollstandzeit>0</_Sollstandzeit>
        <_Iststandzeit>0</_Iststandzeit>
        <_Vorwarngrenze>0</_Vorwarngrenze>
        <_Laenge_L1>0</_Laenge_L1>
        <_Laenge_L2>0</_Laenge_L2>
        <_Radius>0</_Radius>
      </Schneide_1>
    </Platz_2>
  </INDUSTRIE_WKZ_2>
</Maschine>

(包括输出文件中的XML声明是基于this answer)