繁体   English   中英

从python中的ElementTree中删除空白的lxml元素

[英]Removing blank lxml element from ElementTree in python

我已经为此苦苦挣扎了几天,我想我会在这里问。

我正在准备 XML 有效负载以 POST 到包含财务数据的 Oracle 端点。 我已经按照 Oracle 规范构建了大部分 XML,但是我在其中的一个方面苦苦挣扎。 这是将提供给总账财务系统的数据,xml 结构如下(为了减少帖子,省略了一些元素。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://xmlns.oracle.com/apps/financials/generalLedger/journals/desktopEntry/journalImportService/types/" xmlns:jour="http://xmlns.oracle.com/apps/financials/generalLedger/journals/desktopEntry/journalImportService/">
  <soapenv:Header/>
  <soapenv:Body>
    <typ:importJournals>
      <typ:interfaceRows>
        <jour:BatchName>batch</jour:BatchName>
        <jour:AccountingPeriodName>Aug-20</jour:AccountingPeriodName>
        <jour:AccountingDate>2020-08-31</jour:AccountingDate>
        <jour:GlInterface>
          <jour:LedgerId>1234567890</jour:LedgerId>
          <jour:PeriodName>Aug-20</jour:PeriodName>
          <jour:AccountingDate>2020-08-31</jour:AccountingDate>
          <jour:Segment1>1</jour:Segment1>
          <jour:Segment2>1</jour:Segment2>
          <jour:Segment3>1</jour:Segment3>
          <jour:Segment4>1</jour:Segment4>
          <jour:Segment5>0</jour:Segment5>
          <jour:Segment6>0</jour:Segment6>
          <jour:CurrencyCode>USD</jour:CurrencyCode>
          <jour:EnteredCrAmount currencyCode="USD">10.0000</jour:EnteredCrAmount>
        </jour:GlInterface>
        <jour:GlInterface>
          <jour:LedgerId>1234567890</jour:LedgerId>
          <jour:PeriodName>Aug-20</jour:PeriodName>
          <jour:AccountingDate>2020-08-31</jour:AccountingDate>
          <jour:Segment1>2</jour:Segment1>
          <jour:Segment2>2</jour:Segment2>
          <jour:Segment3>2</jour:Segment3>
          <jour:Segment4>2</jour:Segment4>
          <jour:Segment5>0</jour:Segment5>
          <jour:Segment6>0</jour:Segment6>
          <jour:CurrencyCode>USD</jour:CurrencyCode>
          <jour:EnteredDrAmount currencyCode="USD">10.0000</jour:EnteredCrAmount>
        </jour:GlInterface>
      </typ:interfaceRows>
    </typ:importJournals>
  </soapenv:Body>
</soapenv:Envelope>

因此,如果您查看上面的 XML,在 GlInterface 标记中,每笔交易有 2 个(一个是借方,一个是贷方,如果您查看 Segments(帐户代码),它们是不同的,一个 GlInterface 标记作为EnteredDrAmount 标签,而另一个有 EnteredCrAmount 标签。

在源数据中,Cr 或 Dr 标记为空,具体取决于行是借方还是贷方,在 python 中显示为“无”。

我让它工作的方法是调用两个调用来获取数据,一个是 Cr 不为空,一个是 Dr 不为空,这个过程工作正常,但在 Python 中,我得到一个错误“只有一个 * 允许” . 代码如下。

    xmlOracle = x_Envelope(
        x_Header,
        x_Body(
            x_importJournals(
                x_interfaceRows(
                    x_h_BatchName(str(batch[0])),
                    x_h_AccountingPeriodName(str(batch[3])),
                    x_h_AccountingDate(str(batch[4])),
                    *[x_GlInterface(
                        x_d_LedgerId(str(adid[0])),
                        x_d_PeriodName(str(adid[1])),
                        x_d_AccountingDate(str(adid[2])),
                        x_d_Segment1(str(adid[5])),
                        x_d_Segment2(str(adid[6])),
                        x_d_Segment3(str(adid[7])),
                        x_d_Segment4(str(adid[8])),
                        x_d_Segment5(str(adid[9])),
                        x_d_Segment6(str(adid[10])),
                        x_d_CurrencyCode(str(adid[11])),
                        x_d_EnteredCrAmount(str(adid[14]), currencyCode=str(adid[11]))
                    ) for adid in CrAdidToProcess],
                    *[x_GlInterface(
                        x_d_LedgerId(str(adid[0])),
                        x_d_PeriodName(str(adid[1])),
                        x_d_AccountingDate(str(adid[2])),
                        x_d_Segment1(str(adid[5])),
                        x_d_Segment2(str(adid[6])),
                        x_d_Segment3(str(adid[7])),
                        x_d_Segment4(str(adid[8])),
                        x_d_Segment5(str(adid[9])),
                        x_d_Segment6(str(adid[10])),
                        x_d_CurrencyCode(str(adid[11])),
                        x_d_EnteredDrAmount(str(adid[14]), currencyCode=str(adid[11]))
                    ) for adid in DrAdidToProcess]
                )
            )
        )
    )

我也试过打一个电话来获取线路详细信息,然后删除或过滤掉标签(Cr 或 Dr),如果它是“无”,但我对此并不走运。

虽然上述过程有效,但我的代码中存在错误,我希望我的代码中没有错误。

谢谢你们。

经过进一步测试,我相信我找到了解决方案。 我相信我试图从 ElementTree 对象中删除一个元素,但它没有任何元素。 当我将一个元素传递给 remove 方法/函数时,它终于起作用了。

这是删除“无”条目的函数的代码。

def removeCrDrEmptyElements(element):
    for removeElement in element.xpath('/soapenv:Envelope/soapenv:Body/typ:importJournals/typ:interfaceRows/jour:GlInterface/jour:EnteredCrAmount',
                                         namespaces = { 'soapenv' : 'http://schemas.xmlsoap.org/soap/envelope/',
                                                        'typ' : 'http://xmlns.oracle.com/apps/financials/generalLedger/journals/desktopEntry/journalImportService/types/',
                                                        'jour' : 'http://xmlns.oracle.com/apps/financials/generalLedger/journals/desktopEntry/journalImportService/'
                                                      }):
        if removeElement.text == 'None':
            removeElement.getparent().remove(removeElement)

    for removeElement in element.xpath('/soapenv:Envelope/soapenv:Body/typ:importJournals/typ:interfaceRows/jour:GlInterface/jour:EnteredDrAmount',
                                         namespaces = { 'soapenv' : 'http://schemas.xmlsoap.org/soap/envelope/',
                                                        'typ' : 'http://xmlns.oracle.com/apps/financials/generalLedger/journals/desktopEntry/journalImportService/types/',
                                                        'jour' : 'http://xmlns.oracle.com/apps/financials/generalLedger/journals/desktopEntry/journalImportService/'
                                                      }):
        if removeElement.text == 'None':
            removeElement.getparent().remove(removeElement)

    return element

显然,这可以更好地重写(我会这样做),但我只想检查 GlInterface 标记中的两个元素,即 EnteredCrAmount 和 EnteredDrAmount,如果文本为 None,则删除这些元素。

然后,您可以使用以下代码调用该函数,以返回带有已删除 Nulls/Nones 的元素类型

xmlWithoutNull = removeCrDrEmptyElements(xmlElement)

运行函数结果前的输出:

        <jour:GlInterface>
          # omitted elements
          <jour:EnteredCrAmount currencyCode="USD">1.000000</jour:EnteredCrAmount>
          <jour:EnteredDrAmount currencyCode="USD">None</jour:EnteredDrAmount>
          # omitted elements
        </jour:GlInterface>
        <jour:GlInterface>
          # omitted elements
          <jour:EnteredCrAmount currencyCode="USD">None</jour:EnteredCrAmount>
          <jour:EnteredDrAmount currencyCode="USD">1.000000</jour:EnteredDrAmount>
          # omitted elements
        </jour:GlInterface>

运行函数结果后输出:

        <jour:GlInterface>
          # omitted elements
          <jour:EnteredCrAmount currencyCode="USD">1.000000</jour:EnteredCrAmount>
          # omitted elements
        </jour:GlInterface>
        <jour:GlInterface>
          # omitted elements
          <jour:EnteredDrAmount currencyCode="USD">1.000000</jour:EnteredDrAmount>
          # omitted elements
        </jour:GlInterface>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM