修改XML中类似元素的特定子元素

时间:2017-11-24 10:04:06

标签: python xml elementtree

我使用Python和ElementTree尝试修改XML文件,但是只修改了一些元素而不是所有元素都有困难。由于每个元素的结构非常相似,因此出现了困难。这是一个样本:

    <data>
    <Property name="Table">
        <Property value="GenericEntry">
            <Property name="Type" value="GenericType">
                <Property name="InteractionType" value="NPC" />
            </Property>
            <Property name="Options">
              <Property value="OptionTable">
                <Property name="Rewards">
                  <Property value="StringSample">
                    <Property name="Value" value="Whatever" />
                  </Property>
                </Property>
              </Property>
            </Property>
        </Property>
       <Property value="GenericEntry">
            <Property name="Type" value="GenericType">
                <Property name="InteractionType" value="Frog" />
            </Property>
            <Property name="Options">
              <Property value="OptionTable">
                <Property name="Rewards">
                  <Property value="StringSample">
                    <Property name="Value" value="Whatever" />
                  </Property>
                </Property>
              </Property>
            </Property>
        </Property>
        <Property value="GenericEntry">
            <Property name="Type" value="GenericType">
                <Property name="InteractionType" value="NPC" />
            </Property>
            <Property name="Options">
              <Property value="OptionTable">
                <Property name="Rewards">
                  <Property value="StringSample">
                    <Property name="Value" value="Whatever" />
                  </Property>
                </Property>
              </Property>
            </Property>
        </Property>
    </Property>
  </data>

我试图将子元素添加到任意数量的具有NPC类型的GenericEntries,特别是在Rewards下。但是,目前,我只能解决如何将子元素添加到所有GenericEntries中,无论其类型如何。

这是我到目前为止所编写的代码:

for glance in root.findall("./Property/Property"):
    see = glance.find(".//Property[@name='InteractionType']").get('value')
    if see == "NPC": #Obviously not the right track...
    for gah in root.findall("./Property/Property/Property[@name='Options']"):
        aha = gah.find("./Property/Property[@name='Rewards']")
        here = ET.SubElement(aha, "Property", value='StringSample')
        there = ET.SubElement(here, "Property", name='Value', value='Boop')

我尝试缩小findall / find方法,因为我已经完成了这项工作,但是我一直在尝试使用块,因为它对于任意数量的条目来说更具有广泛的可扩展性。但是,我似乎过度纠正了。

简而言之,目的是重写它以识别某些条目类型,并通过向它们添加子元素来修改这些指定类型的多个条目。

预期输出将如下所示:

    <data>
    <Property name="Table">
        <Property value="GenericEntry">
            <Property name="Type" value="GenericType">
                <Property name="InteractionType" value="NPC" />
            </Property>
            <Property name="Options">
              <Property value="OptionTable">
                <Property name="Rewards">
                  <Property value="StringSample">
                    <Property name="Value" value="Whatever" />
                  </Property>
                  <Property value="StringSample">
                    <Property name="Value" value="Boop" />
                  </Property>
                </Property>
              </Property>
            </Property>
        </Property>
       <Property value="GenericEntry">
            <Property name="Type" value="GenericType">
                <Property name="InteractionType" value="Frog" />
            </Property>
            <Property name="Options">
              <Property value="OptionTable">
                <Property name="Rewards">
                  <Property value="StringSample">
                    <Property name="Value" value="Whatever" />
                  </Property>
                </Property>
              </Property>
            </Property>
        </Property>
        <Property value="GenericEntry">
            <Property name="Type" value="GenericType">
                <Property name="InteractionType" value="NPC" />
            </Property>
            <Property name="Options">
              <Property value="OptionTable">
                <Property name="Rewards">
                  <Property value="StringSample">
                    <Property name="Value" value="Whatever" />
                  </Property>
                  <Property value="StringSample">
                    <Property name="Value" value="Boop" />
                  </Property>
                </Property>
              </Property>
            </Property>
        </Property>
    </Property>
  </data>

1 个答案:

答案 0 :(得分:1)

你可以试试这个:

# select Property's with specific value, move to parent's parent (/../.. = <Property value="GenericEntry">)
for gah in root.findall('.//Property[@name="InteractionType"][@value="NPC"]/../..'):
    aha = gah.find('.//Property[@name="Rewards"]')
    here = ET.SubElement(aha, "Property", value='StringSample')
    there = ET.SubElement(here, "Property", name='Value', value='Boop')