问题描述
我已经为此苦苦挣扎了几天,我想我会在这里问。
我正在准备一个XML有效载荷,以便过帐到包含财务数据的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个(一个是借方,一个是贷方,如果您查看细分(帐户代码)不同),则一个GlInterface标签作为EnteredDrAmount标签,而另一个具有EnteredCrAmount标签。
在源数据中,Cr或Dr标签为空,具体取决于行是借方还是贷方,在python中为“ None”。
我使用此方法的方式是调用两个调用以获取数据,一个调用中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_d_EnteredDrAmount(str(adid[14]),currencyCode=str(adid[11]))
) for adid in DrAdidToProcess]
)
)
)
)
我还尝试过一次调用以获取行的详细信息,然后删除或过滤掉标记(Cr或Dr)(如果标记为“ None”,但我对此没有运气。)
尽管上述过程有效,但是我的代码中有一个错误,并且我希望我的代码中没有错误。
谢谢大家。
解决方法
经过进一步测试,我相信我已经找到解决方案。我相信我试图从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','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则删除这些元素。
然后,您可以使用下面的代码来调用该函数,以返回带有已删除的Null / 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>