使用 ElementTree 和 python 获取 XML Parent ID 和下面的所有 Childs

Get XML Parent ID and all Childs underneath using ElementTree and python

我想从XML那里获得一些信息。

  1. 区域 ID,如果 type-v2="text"
  2. 隐藏在元素中的该特定区域下的所有子项。

这是 XML 代码:

<dashboards>
  <dashboard name="1 off">
   <style/>
   <size maxheight="800" maxwidth="1000" minheight="800" minwidth="1000"/>
   <zones>
    <zone h="100000" id="2" type-v2="layout-basic" w="100000" x="0" y="0">
     <zone forceUpdate="true" h="98000" id="1" type-v2="text" w="49200" x="800" y="1000">
      <formatted-text>
       <run fontsize="1">
        row 1
       </run>
       <run>
        Æ
       </run>
       <run fontsize="2">
        row 2
       </run>
      </formatted-text>
      <zone-style>
       <format attr="border-color" value="#000000"/>
       <format attr="border-style" value="none"/>
       <format attr="border-width" value="0"/>
       <format attr="margin" value="4"/>
      </zone-style>
     </zone>
     <zone h="98000" id="3" type-v2="text" w="49200" x="50000" y="1000">
      <formatted-text>
       <run>
        id2
       </run>
      </formatted-text>
      <zone-style>
       <format attr="border-color" value="#000000"/>
       <format attr="border-style" value="none"/>
       <format attr="border-width" value="0"/>
       <format attr="margin" value="4"/>
      </zone-style>
     </zone>
     <zone-style>
      <format attr="border-color" value="#000000"/>
      <format attr="border-style" value="none"/>
      <format attr="border-width" value="0"/>
      <format attr="margin" value="8"/>
     </zone-style>
    </zone>
   </zones>
  </dashboard>
</dashboards>

我可以单独获取 运行 中的所有 ID 和所有详细信息,但我想获得不同的输出。 所以我想为每个元素分配父 ID。

这是我单独获取信息的代码:

import xml.etree.ElementTree as et

tree = et.parse(r'C:\book3.twb')
root = tree.getroot()
dbnameRC=[]
fontRC = []
sizeRC = []
weightRC = []
f_styleRC = []
decoRC = []
colorRC= []
alignRC = []
textcontRC=[]
idRC=[]

for db in root.iter("dashboard"):
    root1 = db    
    
    for z in root1.findall(".//zone[@type-v2='text']"):
        idRC.append(z.get('id'))

    for m in root1.findall(".//zone[@type-v2='text']/formatted-text//run"):
        weightRC.append(m.get('bold'))
        alignRC.append(m.get('fontalignment'))
        colorRC.append(m.get('fontcolor'))
        fontRC.append(m.get('fontname'))
        sizeRC.append(m.get('fontsize'))
        f_styleRC.append(m.get('italic'))
        decoRC.append(m.get('underline'))
        dbnameRC.append(db.attrib['name'])
        textcontRC.append(m.text)
        

1.the idRC 的输出是:

 ['1', '3'] 

这是正确的,因为我们只有两个 type-v2='text']

的 id
  1. sizeRC 的输出是
['1', None, '2', None]

这也是正确的。

问题是如何编写代码作为这样的输出:

基本上我想要做的就是使用 type-v2="text" 进入区域获取它的 id 并将所有 运行s 放在下面并将其分配给这个特定的 id 然后移动到另一个区域不同的 id 和
type-v2="text" 并获取该区域下的所有 运行。

您可以 zone.findall() 而不是第二个 root1.findall() - 允许您将 id 与每个 运行.

分组
runs = []

for db in root.iter("dashboard"):
    root1 = db

    for zone in root1.findall(".//zone[@type-v2='text']"):
        idrc = zone.get('id')

        for run in zone.findall("./formatted-text//run"):
            runs.append([
                idrc,
                run.get("bold"),
                run.get("fontalignment"),
                run.get("fontcolor"),
                run.get("fontname"),
                run.get("fontsize"),
                run.get("italic"),
                run.get("underline"),
                db.attrib["name"],
                run.text
            ])

输出:

>>> runs
[['1', None, None, None, None, '1', None, None, '1 off', 'row 1'],
 ['1', None, None, None, None, None, None, None, '1 off', 'Æ'],
 ['1', None, None, None, None, '2', None, None, '1 off', 'row 2'],
 ['3', None, None, None, None, None, None, None, '1 off', 'id2']]