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

Modifying specific subelements of similar elements in XML

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

我正在尝试向任意数量的 GenericEntries 添加一个子元素,只有 涉及 NPC 类型,特别是在奖励下。但是,目前,我只能弄清楚如何向所有 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>

你可以试试这个:

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