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)
我正在使用 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)