2016-03-29 115 views
0

我已經嘗試了2種方法來替換XML文件中給定節點內的值,它不工作。python替換xml值

我的文件:

<?xml version="1.0" encoding="UTF-8"?> 
 
<OrdSet xmlns="tfs" xmlns:xsi="http://www.sample.org/XMLSchema-instance" xsi:schemaLocation="tfs tfs.xsd" Version="25"> 
 
    <Msg> 
 
     <MsgCreate> 
 
      <Date>20160324</Date> 
 
      <Time>111057</Time> 
 
      <Src> 
 
       <SrcType>D</SrcType> 
 
       <DlrCode>0001</DlrCode> 
 
      </Src> 
 
      <Target> 
 
       <TargetType>F</TargetType> 
 
       <MgmtCode>BTG</MgmtCode> 
 
      </Target> 
 
     </MsgCreate> 
 
     <MsgType> 
 
      <OrdReq> 
 
       <ActnCode>NEW</ActnCode> 
 
       <SrcID>64698602107101</SrcID> 
 
       <RepCode>0000</RepCode> 
 
       <OrdDtl> 
 
        <AcctLookup> 
 
         <MgmtCode>ABC</MgmtCode> 
 
         <FundAcctID>984575</FundAcctID> 
 
         <AcctDesig>2</AcctDesig> 
 
        </AcctLookup> 
 
        <TrxnDtl> 
 
         <Buy> 
 
          <TrxnTyp>5</TrxnTyp> 
 
          <FundID>205</FundID> 
 
          <Amt> 
 
           <AmtType>D</AmtType> 
 
           <AmtValue>600.00</AmtValue> 
 
          </Amt> 
 
         </Buy> 
 
        </TrxnDtl> 
 
       </OrdDtl> 
 
      </OrdReq> 
 
     </MsgType> 
 
    </Msg> 
 
omitted ...

我的目標是到ActnCode值替換從新到CAN。

I.e., <ActnCode>CAN</ActnCode>

嘗試#1:腳本運行良好,但數值仍然是 「新建」,在輸出文件中。似乎沒有任何改變。

import xml.etree.ElementTree as ET 
 
tree = ET.parse("~\input.xml") 
 
root = tree.getroot() 
 
elems = tree.findall('ActnCode') 
 
for elem in elems: 
 
\t elem.txt = 'CAN' 
 
tree.write("~\output.xml")

嘗試#2:腳本正確運行很好,但如預期它不工作。

xmldoc = minidom.parse('~input.xml') 
 
action_code = xmldoc.getElementsByTagName('ActnCode') 
 
firstchild = action_code[0] 
 
firstchild.setAttribute('ActnCode', 'CAN') 
 

 
result: 
 
<ActnCode ActnCode="CAN">NEW</ActnCode>

最後,我想蟒蛇通過XML文檔看,發現所有ActnCode節點,將值更改爲 「CAN」。任何幫助將不勝感激。

+0

這在XSLT中是微不足道的。你可以使用*** lxml ***代替etree來運行XSLT轉換嗎? –

回答

0

你有幾個問題。您正在查找的元素具有從<OrdSet xmlns="..."中的默認名稱空間繼承的名稱空間,並且需要將其包含在查找中。然後,findall只會看到孩子,除非您添加ElementTree的「pseudo-xsl」子樹搜索模式。最後,您需要更改text屬性,而不是`txt。

縮XML測試...

<?xml version="1.0" encoding="UTF-8"?> 
<OrdSet xmlns="tfs"> 
    <Msg> 
     <MsgCreate> 
      <ActnCode>NEW</ActnCode> 
      <SrcID>64698602107101</SrcID> 
      <RepCode>0000</RepCode> 
      <OrdDtl> 
       <AcctLookup> 
        <MgmtCode>ABC</MgmtCode> 
        <FundAcctID>984575</FundAcctID> 
        <AcctDesig>2</AcctDesig> 
       </AcctLookup> 
      </OrdDtl> 
     </MsgCreate> 
    </Msg> 
</OrdSet> 

並且代碼

import xml.etree.ElementTree as ET 
tree = ET.parse("input.xml") 
root = tree.getroot() 
elems = tree.findall('.//{http://abc}ActnCode') 
print('elems', elems) 
for elem in elems: 
    elem.text = 'CAN' 
tree.write("output.xml") 

編輯

你可以用lxml做更復雜的XPath查詢比ElementTree。如果您想限制您處理的元素,此謂詞將查看其他元素以優化選擇。尖括號內的東西本質上是一個過濾器,它將刪除不匹配的節點。這裏我限制了兄弟節點OrdDtl/AcctLookup/FundAcctID爲984575

import lxml.etree 
tree = lxml.etree.parse('input.xml') 
elems = tree.xpath('//tfs:ActnCode[../tfs:OrdDtl/tfs:AcctLookup/tfs:FundAcctID/text()="984575"]', 
    namespaces={'tfs':'tfs'}) 
elems2 = tree.xpath('.//tfs:ActnCode[../tfs:OrdDtl]', 
    namespaces={'tfs':'tfs'}) 
print('elems', elems) 
for elem in elems: 
    elem.text = 'CAN' 
tree.write("output.xml") 
+0

它完美地工作。謝謝! – spiderlily

+0

我遇到了另一個問題。我如何修改代碼,以便僅在FundAcctID爲984575時纔會將ActnCode更改爲「CAN」? – spiderlily

+0

您可以將謂詞添加到搜索表達式中,但是ElemenTree的謂詞支持是有限的。我將提供另一個使用'lxml'和XPATH謂詞的例子。 – tdelaney