参照dataframe替换XML中的元素
我正在使用lxml读取我的xml文件:参照dataframe替换XML中的元素,xml,pandas,lxml,Xml,Pandas,Lxml,我正在使用lxml读取我的xml文件: tree = etree.parse(r'C:\Users\xxx\Desktop\misc work\xmledit\SalesTransactionCustom.xml') 并获取一个xml文件,如: <?xml version="1.0" encoding="UTF-8"?> <ProcessSalesTransactionCustom xmlns="http://schema.xxxx.com/xxxxx/2" releaseI
tree = etree.parse(r'C:\Users\xxx\Desktop\misc work\xmledit\SalesTransactionCustom.xml')
并获取一个xml文件,如:
<?xml version="1.0" encoding="UTF-8"?>
<ProcessSalesTransactionCustom xmlns="http://schema.xxxx.com/xxxxx/2" releaseID="9.2">
<ApplicationArea>
<Sender>
<LogicalID>xxxxxx.file.syncxxxxx5salesinvoice</LogicalID>
<ComponentID>External</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2020-04-16T14:50:26.976Z</CreationDateTime>
<BODID>xxxx-nid:xxxxx:1001::Default_1001#320000:?SalesTransactionCustom&verb=Process</BODID>
</ApplicationArea>
<DataArea>
<Process>
<TenantID>xxx</TenantID>
<AccountingEntityID>4710</AccountingEntityID>
<LocationID>S_4710</LocationID>
<ActionCriteria>
<ActionExpression actionCode="Add"/>
</ActionCriteria>
</Process>
<SalesTransactionCustom>
<FinancialBatch>
<TransactionDate>2019-09-27T00:00:00</TransactionDate>
<BatchReference>KUKS_20190928052427</BatchReference>
</FinancialBatch>
<TransactionHeader>
<TransactionType>HEI</TransactionType>
<SalesInvoice>
<Invoice>19001160</Invoice>
<BusinessPartner>417B00</BusinessPartner>
<DocumentDate>2019-09-27T00:00:00</DocumentDate>
<DueDate>2019-11-20T00:00:00</DueDate>
<Amount>152248.80</Amount>
<Currency>EUR</Currency>
<TaxCountry>DK</TaxCountry>
<TaxCode>BESIT</TaxCode>
<NonFinalizedTransaction>
<TransactionReference>417B00 PC210LCI-11</TransactionReference>
<LedgerAccount>50000400</LedgerAccount>
<Dimension1>100</Dimension1>
<Dimension2>KUK</Dimension2>
<Dimension3/>
<Dimension4/>
<Dimension5/>
<Dimension6/>
<Dimension7/>
<Dimension8/>
<TaxAmount>0.00</TaxAmount>
<DebitCreditFlag>credit</DebitCreditFlag>
<Amount>152248.80</Amount>
</NonFinalizedTransaction>
</SalesInvoice>
</TransactionHeader>
<TransactionHeader>
<TransactionType>HEI</TransactionType>
<SalesInvoice>
<Invoice>19001161</Invoice>
<BusinessPartner>412600</BusinessPartner>
<DocumentDate>2019-09-27T00:00:00</DocumentDate>
<DueDate>2019-11-20T00:00:00</DueDate>
<Amount>113848.17</Amount>
<Currency>EUR</Currency>
<TaxCountry>AT</TaxCountry>
<TaxCode>GBSI</TaxCode>
<NonFinalizedTransaction>
<TransactionReference>412600 PC210NLC-11</TransactionReference>
<LedgerAccount>50000400</LedgerAccount>
<Dimension1>100</Dimension1>
<Dimension2>KUK</Dimension2>
<Dimension3/>
<Dimension4/>
<Dimension5/>
<Dimension6/>
<Dimension7/>
<Dimension8/>
<TaxAmount>0.00</TaxAmount>
<DebitCreditFlag>credit</DebitCreditFlag>
<Amount>113848.17</Amount>
</NonFinalizedTransaction>
</SalesInvoice>
</TransactionHeader>
</SalesTransactionCustom>
</DataArea>
</ProcessSalesTransactionCustom>
我想用这个数据框架替换xml中元素的属性。我希望能够找到标记和旧值的组合,并用新值替换属性。我还需要能够将编辑后的文本作为XML写回磁盘
我如何使用lxml和pandas实现这一点
先谢谢你
编辑:这是感谢@Partha Mandal的代码
import pandas as pd
from lxml import etree
df=pd.read_excel("Sample.xlsx")
df.columns=['Tag','Old','New']
df['Old'] = df['Old'].astype(str)
df['New'] = df['New'].astype(str)
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse(r'C:\Users\xxx\Desktop\misc work\xmledit\testxml2.xml',parser)
string = etree.tostring(tree)
string = bytes.decode(string)
tag = df.Tag; old = df.Old; new = df.New
for i in range(len(tag)):
string = string.replace("<"+tag[i]+">"+old[i]+"</"+tag[i]+">","<"+tag[i]+">"+new[i]+"</"+tag[i]+">")
string=str.encode(string)
root = etree.fromstring(string)
my_tree = etree.ElementTree(root)
with open('testxml2.xml', 'wb') as f:
f.write(etree.tostring(my_tree))
将熊猫作为pd导入
从lxml导入etree
df=pd.read\u excel(“Sample.xlsx”)
df.columns=['Tag','Old','New']
df['Old']=df['Old'].astype(str)
df['New']=df['New'].astype(str)
parser=etree.XMLParser(删除\u blank\u text=True)
tree=etree.parse(r'C:\Users\xxx\Desktop\misc work\xmledit\testxml2.xml',解析器)
string=etree.tostring(树)
字符串=字节。解码(字符串)
tag=df.tag;old=df.old;new=df.new
对于范围内的i(len(tag)):
string=string.replace(“+old[i]+”、“+new[i]+”)
string=str.encode(字符串)
root=etree.fromstring(字符串)
my_tree=etree.ElementTree(根)
将open('testxml2.xml','wb')作为f:
f、 写入(etree.tostring(我的树))
为什么不将XML
作为字符串读取,然后执行str.replace
tag = df.Tag; old = df.Old; new = df.New
for i in range(len(tag)):
_str = _str.replace("<"+tag[i]+">"+old[i]+"</"+tag[i]+">","<"+tag[i]+">"+new[i]+"</"+tag[i]+">")
tag=df.tag;old=df.old;new=df.new
对于范围内的i(len(tag)):
_str=_str.replace(“+old[i]+”,“+new[i]+”)
<代码> > p>因为使用<代码> LXML<代码>,请考虑将专用XML语言转换为不同XML的专用语言,并支持从顶层如Python传递参数。因此,在数据帧记录的循环中集成参数化:
唯一的挑战是将标记的所有唯一值硬编码到XSLT的第二个模板匹配中(管道正常后换行):
doc:BusinessPartner | doc:LedgerAccount
你可以用它
“|”。join(['doc:'+val表示df['Tag'].unique()中的val)
“|\n”.join(['doc:'+val代表df['Tag'].unique()中的val)
XSLT(另存为.xsl,一个特殊的.xml文件)
XML输出
<?xml version="1.0"?>
<ProcessSalesTransactionCustom xmlns="http://schema.xxxx.com/xxxxx/2" releaseID="9.2">
<ApplicationArea>
<Sender>
<LogicalID>xxxxxx.file.syncxxxxx5salesinvoice</LogicalID>
<ComponentID>External</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2020-04-16T14:50:26.976Z</CreationDateTime>
<BODID>xxxx-nid:xxxxx:1001::Default_1001#320000:?SalesTransactionCustom&verb=Process</BODID>
</ApplicationArea>
<DataArea>
<Process>
<TenantID>infor</TenantID>
<AccountingEntityID>4710</AccountingEntityID>
<LocationID>S_4710</LocationID>
<ActionCriteria>
<ActionExpression actionCode="Add"/>
</ActionCriteria>
</Process>
<SalesTransactionCustom>
<FinancialBatch>
<TransactionDate>2019-09-27T00:00:00</TransactionDate>
<BatchReference>KUKS_20190928052427</BatchReference>
</FinancialBatch>
<TransactionHeader>
<TransactionType>HEI</TransactionType>
<SalesInvoice>
<Invoice>19001160</Invoice>
<BusinessPartner>BPE000104</BusinessPartner>
<DocumentDate>2019-09-27T00:00:00</DocumentDate>
<DueDate>2019-11-20T00:00:00</DueDate>
<Amount>152248.80</Amount>
<Currency>EUR</Currency>
<TaxCountry>DK</TaxCountry>
<TaxCode>BESIT</TaxCode>
<NonFinalizedTransaction>
<TransactionReference>417B00 PC210LCI-11</TransactionReference>
<LedgerAccount>108092200</LedgerAccount>
<Dimension1>100</Dimension1>
<Dimension2>KUK</Dimension2>
<Dimension3/>
<Dimension4/>
<Dimension5/>
<Dimension6/>
<Dimension7/>
<Dimension8/>
<TaxAmount>0.00</TaxAmount>
<DebitCreditFlag>credit</DebitCreditFlag>
<Amount>152248.80</Amount>
</NonFinalizedTransaction>
</SalesInvoice>
</TransactionHeader>
<TransactionHeader>
<TransactionType>HEI</TransactionType>
<SalesInvoice>
<Invoice>19001161</Invoice>
<BusinessPartner>BPE000153</BusinessPartner>
<DocumentDate>2019-09-27T00:00:00</DocumentDate>
<DueDate>2019-11-20T00:00:00</DueDate>
<Amount>113848.17</Amount>
<Currency>EUR</Currency>
<TaxCountry>AT</TaxCountry>
<TaxCode>GBSI</TaxCode>
<NonFinalizedTransaction>
<TransactionReference>412600 PC210NLC-11</TransactionReference>
<LedgerAccount>108092200</LedgerAccount>
<Dimension1>100</Dimension1>
<Dimension2>KUK</Dimension2>
<Dimension3/>
<Dimension4/>
<Dimension5/>
<Dimension6/>
<Dimension7/>
<Dimension8/>
<TaxAmount>0.00</TaxAmount>
<DebitCreditFlag>credit</DebitCreditFlag>
<Amount>113848.17</Amount>
</NonFinalizedTransaction>
</SalesInvoice>
</TransactionHeader>
</SalesTransactionCustom>
</DataArea>
</ProcessSalesTransactionCustom>
xxxxxx.file.syncxxxxx5salesinvoice
外部的
一个错误
2020-04-16T14:50:26.976Z
xxxx nid:xxxxx:1001::默认值为#1001#320000:?SalesTransactionCustom&;动词=过程
信息
4710
S_4710
2019-09-27T00:00:00
KUKS_20190928052427
嗨
19001160
BPE0000104
2019-09-27T00:00:00
2019-11-20T00:00:00
152248.80
欧元
DK
贝西特
417B00 PC210LCI-11
108092200
100
库克
0
信用
152248.80
嗨
19001161
BPE00153
2019-09-27T00:00:00
2019-11-20T00:00:00
113848.17
欧元
在
GBSI
412600 PC210NLC-11
108092200
100
库克
0
信用
113848.17
我添加此代码是为了将其作为字符串读取—“string=etree.tostring(tree)”。然后,我在您的注释中运行for循环,但没有下划线(因为我不确定这是为了什么,也没有定义这样的变量)。因此,我使用'string'而不是'u str'运行for循环,但得到以下错误:TypeError:需要一个类似字节的对象,而不是'str'。在运行str.replace之前,您可以运行string=bytes.decode(string)
?谢谢。我照你说的做了,字符串现在被编辑了。但是,我还需要将其作为XML写回磁盘。(我已经编辑了这个问题)我正在用open('sample2.xml',wb')作为f:string.write(f,encoding=“utf-8”,xml\u declaration=True,pretty\u print=True)尝试代码-,
但是得到的错误是“bytes”对象没有属性“write”。(我再次尝试解码成字符串,但是用'str'而不是'bytes'得到了相同的错误)哦!您是否应该使用f.write…
,这可能就是问题所在?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://schema.xxxx.com/xxxxx/2">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- PARAMETERS -->
<xsl:param name="tag" />
<xsl:param name="old_value" />
<xsl:param name="new_value" />
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- CONDITIONALL ASSIGN PARAMS -->
<xsl:template match="doc:BusinessPartner|doc:LedgerAccount">
<xsl:choose>
<xsl:when test = "text() = $old_value">
<xsl:copy>
<xsl:value-of select="$new_value"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:value-of select="text()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
import pandas as pd
import lxml.etree as et
df = pd.read_csv(...)
# LOAD XML AND XSL SCRIPT
xml = et.parse('Input.xml')
xsl = et.parse('Script.xsl')
transform = et.XSLT(xsl)
# PASS PARAMETER TO XSLT
df_list = df.to_dict('records')
for v in df_list:
result = transform(xml, tag = et.XSLT.strparam(v['Tag']),
old_value = et.XSLT.strparam(v['Old Value']),
new_value = et.XSLT.strparam(v['New Value']))
xml = result
# SAVE TO NEW XML
with open("Output.xml", 'wb') as f:
f.write(result)
<?xml version="1.0"?>
<ProcessSalesTransactionCustom xmlns="http://schema.xxxx.com/xxxxx/2" releaseID="9.2">
<ApplicationArea>
<Sender>
<LogicalID>xxxxxx.file.syncxxxxx5salesinvoice</LogicalID>
<ComponentID>External</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2020-04-16T14:50:26.976Z</CreationDateTime>
<BODID>xxxx-nid:xxxxx:1001::Default_1001#320000:?SalesTransactionCustom&verb=Process</BODID>
</ApplicationArea>
<DataArea>
<Process>
<TenantID>infor</TenantID>
<AccountingEntityID>4710</AccountingEntityID>
<LocationID>S_4710</LocationID>
<ActionCriteria>
<ActionExpression actionCode="Add"/>
</ActionCriteria>
</Process>
<SalesTransactionCustom>
<FinancialBatch>
<TransactionDate>2019-09-27T00:00:00</TransactionDate>
<BatchReference>KUKS_20190928052427</BatchReference>
</FinancialBatch>
<TransactionHeader>
<TransactionType>HEI</TransactionType>
<SalesInvoice>
<Invoice>19001160</Invoice>
<BusinessPartner>BPE000104</BusinessPartner>
<DocumentDate>2019-09-27T00:00:00</DocumentDate>
<DueDate>2019-11-20T00:00:00</DueDate>
<Amount>152248.80</Amount>
<Currency>EUR</Currency>
<TaxCountry>DK</TaxCountry>
<TaxCode>BESIT</TaxCode>
<NonFinalizedTransaction>
<TransactionReference>417B00 PC210LCI-11</TransactionReference>
<LedgerAccount>108092200</LedgerAccount>
<Dimension1>100</Dimension1>
<Dimension2>KUK</Dimension2>
<Dimension3/>
<Dimension4/>
<Dimension5/>
<Dimension6/>
<Dimension7/>
<Dimension8/>
<TaxAmount>0.00</TaxAmount>
<DebitCreditFlag>credit</DebitCreditFlag>
<Amount>152248.80</Amount>
</NonFinalizedTransaction>
</SalesInvoice>
</TransactionHeader>
<TransactionHeader>
<TransactionType>HEI</TransactionType>
<SalesInvoice>
<Invoice>19001161</Invoice>
<BusinessPartner>BPE000153</BusinessPartner>
<DocumentDate>2019-09-27T00:00:00</DocumentDate>
<DueDate>2019-11-20T00:00:00</DueDate>
<Amount>113848.17</Amount>
<Currency>EUR</Currency>
<TaxCountry>AT</TaxCountry>
<TaxCode>GBSI</TaxCode>
<NonFinalizedTransaction>
<TransactionReference>412600 PC210NLC-11</TransactionReference>
<LedgerAccount>108092200</LedgerAccount>
<Dimension1>100</Dimension1>
<Dimension2>KUK</Dimension2>
<Dimension3/>
<Dimension4/>
<Dimension5/>
<Dimension6/>
<Dimension7/>
<Dimension8/>
<TaxAmount>0.00</TaxAmount>
<DebitCreditFlag>credit</DebitCreditFlag>
<Amount>113848.17</Amount>
</NonFinalizedTransaction>
</SalesInvoice>
</TransactionHeader>
</SalesTransactionCustom>
</DataArea>
</ProcessSalesTransactionCustom>