通过 xPath 和条件使用 Python 附加 XML 元素

问题描述 投票:0回答:1

我第一次公开写下问题。

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

我想将一个新的 price 元素附加到 prices 块,如果 .//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 内和流量控制中进行检查。但要么我在每个 prices 元素中附加一个新的 price 元素,要么什么也不会发生。

我的流程控制问题是,我不明白如何告诉 .append 方法“新”路径在哪里。由于追加方法中的“prices_xpath”,以下示例返回 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',但 pricesprice 不是 name 的子级。 价格名称处于同一水平。

python xml xpath append elementtree
1个回答
0
投票

如果我理解正确,您将在价格标签下延长第二个价格: (您的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>
© www.soinside.com 2019 - 2024. All rights reserved.