通过 xPath 和 condition 将 XML 元素与 Python 一起追加

Append XML element with Python by xPath and condition

提问人:Sch0lli 提问时间:10/5/2023 最后编辑:wovanoSch0lli 更新时间:10/6/2023 访问量:58

问:

我想将 ET.fromstring 元素附加到 XML 文件,但前提是满足特殊条件。

我想在价格块中附加一个新的价格元素,如果 .//tariff/name == 'H-AT'。

这里是我的XML示例:

<tariffimport>
    <tariff>
        <tariffFormula>
            <name>K-Watt</name>
        </tariffFormula>
        <status>1</status>
        <parentTariffId />
        <priority>10</priority>
        <i18n>
            <lang>
                <locale>de_DE</locale>
                <shortDescription />
            </lang>
        </i18n>
        <name>H-AT</name>
        <signatureRequired>false</signatureRequired>
        <termExtension>1</termExtension>
        <termExtensionUnit>5</termExtensionUnit>
        <cancellationPeriod>2</cancellationPeriod>
        <cancellationPeriodUnit>3</cancellationPeriodUnit>
        <contractTerm>2</contractTerm>
        <contractTermUnit>3</contractTermUnit>
        <states />
        <counties />
        <excludeCounties />
        <postalCodes />
        <excludePostalCodes />
        <cities>
            <value>town</value>
        </cities>
        <excludeCities />
        <streets />
        <networkOperatorNos />
        <excludeNetworkOperatorNos />
        <customerGroups>
            <value>PRIVATE</value>
        </customerGroups>
        <media>POWER</media>
        <image>../images/stecker.jpg</image>
        <tariffType>1</tariffType>
        <tariffPart>
            <name>AP_1</name>
            <i18n>
                <lang>
                    <locale>de_DE</locale>
                    <displayName>Arbeitspreis</displayName>
                    <shortName />
                    <description />
                    <attributes>
                        <attribute>
                            <key>minConsumption</key>
                            <value>0</value>
                            <priority>4</priority>
                        </attribute>
                        <attribute>
                            <key>maxConsumption</key>
                            <value>4999</value>
                            <priority>5</priority>
                        </attribute>
                    </attributes>
                </lang>
            </i18n>
            <prices>
                <price>
                    <currency>EUR</currency>
                    <value>0,48018</value>
                    <isPercentage>false</isPercentage>
                    <modifyPart />
                    <validfromdate>01.04.2023</validfromdate>
                </price>
            </prices>

我尝试在 xpath 和流量控制中检查。但是,要么我在每个价格元素中附加一个新的价格元素,要么什么也没发生。

我对流控制的问题是,我不明白如何告诉 .append 方法“新”路径在哪里。由于 append 方法中的“prices_xpath”,以下 expample 返回 TypeError。这只是一个例子,我想指导的地方和新的区块。

prices_xpath = './/tariff/tariffPart/prices'
new_price = ET.fromstring("""
                              <price>
                      <currency>EUR</currency>
                                  <value>0,9999</value>
                      <isPercentage>false</isPercentage>
                                  <modifyPart/>
                                  <validfromdate>01.01.2024</validfromdate>
                  </price>
                    """)

for i in root.findall(tariff_token_xpath):
    if i.find('name').text == 'H-AT': 
        i.append(prices_xpath, new_price)
    else:
        pass

另一个想法是,用 xpath 检查是否有文本 = 'H-AT',但价格和价格不是名称的子项。价格名称处于同一水平。

python xml xpath 追加 elementtree

评论

0赞 LMC 10/5/2023
XML 示例无效,因此该问题不是最小可重现的示例。使其有效,如果可能,请删除一些未被修改的元素以使其更具可读性。
0赞 Hermann12 10/5/2023
您的 xml 有 3 次名称标签,对吗?

答:

0赞 Hermann12 10/5/2023 #1

如果我理解正确,您将在价格标签下附加第二个价格: (您的 xml 代码段格式不正确,我添加了一些标签,请检查,如果我在正确的地方添加了它)

import xml.etree.ElementTree as ET

xml_str="""<?xml version="1.0" encoding="UTF-8"?>
<tariffimport>
    <tariff>
        <tariffFormula>
            <name>K-Watt</name>
        </tariffFormula>
        <status>1</status>
        <parentTariffId />
        <priority>10</priority>
        <i18n>
            <lang>
                <locale>de_DE</locale>
                <shortDescription />
            </lang>
        </i18n>
        <name>H-AT</name>
        <signatureRequired>false</signatureRequired>
        <termExtension>1</termExtension>
        <termExtensionUnit>5</termExtensionUnit>
        <cancellationPeriod>2</cancellationPeriod>
        <cancellationPeriodUnit>3</cancellationPeriodUnit>
        <contractTerm>2</contractTerm>
        <contractTermUnit>3</contractTermUnit>
        <states />
        <counties />
        <excludeCounties />
        <postalCodes />
        <excludePostalCodes />
        <cities>
            <value>town</value>
        </cities>
        <excludeCities />
        <streets />
        <networkOperatorNos />
        <excludeNetworkOperatorNos />
        <customerGroups>
            <value>PRIVATE</value>
        </customerGroups>
        <media>POWER</media>
        <image>../images/stecker.jpg</image>
        <tariffType>1</tariffType>
        <tariffPart>
            <name>AP_1</name>
            <i18n>
                <lang>
                    <locale>de_DE</locale>
                    <displayName>Arbeitspreis</displayName>
                    <shortName />
                    <description />
                    <attributes>
                        <attribute>
                            <key>minConsumption</key>
                            <value>0</value>
                            <priority>4</priority>
                        </attribute>
                        <attribute>
                            <key>maxConsumption</key>
                            <value>4999</value>
                            <priority>5</priority>
                        </attribute>
                    </attributes>
                </lang>
            </i18n>
            <prices>
                <price>
                    <currency>EUR</currency>
                    <value>0,48018</value>
                    <isPercentage>false</isPercentage>
                    <modifyPart />
                    <validfromdate>01.04.2023</validfromdate>
                </price>
            </prices>
        </tariffPart>
    </tariff>
</tariffimport>"""

new_price = ET.fromstring("""<price>
  <currency>EUR</currency>
  <value>0,9999</value>
  <isPercentage>false</isPercentage>
  <modifyPart />
  <validfromdate>01.01.2024</validfromdate>
</price>""")

root = ET.fromstring(xml_str)

t = [tex.text for tex in root.findall('.//name')]
if 'H-AT' in t:
    price = root.find('.//prices')
    price.append(new_price)

ET.indent(root, space="  ")
ET.dump(root)
#root.write("new.xml", xml_declaration=True, encoding="utf-8")

输出(短路):

…
<prices>
        <price>
          <currency>EUR</currency>
          <value>0,48018</value>
          <isPercentage>false</isPercentage>
          <modifyPart />
          <validfromdate>01.04.2023</validfromdate>
        </price>
        <price>
          <currency>EUR</currency>
          <value>0,9999</value>
          <isPercentage>false</isPercentage>
          <modifyPart />
          <validfromdate>01.01.2024</validfromdate>
        </price>
      </prices>
    </tariffPart>
  </tariff>
</tariffimport>