2016-08-16 100 views
-1

讓我們假設我有以下XML結構如何重新排序python 3中的XML文檔中的信息?

<?xml version="1.0" encoding="utf-8" ?> 
<Document> 
    <CstmrCdtTrfInitn> 
     <GrpHdr> 
      <other_tags>a</other_tags> <!--here there might be other nested tags inside <other_tags></other_tags>--> 
      <other_tags>b</other_tags> <!--here there might be other nested tags inside <other_tags></other_tags>--> 
      <other_tags>c</other_tags> <!--here there might be other nested tags inside <other_tags></other_tags>--> 
     </GrpHdr> 

     <PmtInf> 
      <things>d</things> <!--here there might be other nested tags inside <things></things>--> 
      <things>e</things> <!--here there might be other nested tags inside <things></things>--> 

      <CdtTrfTxInf> 
       <!-- other nested tags here --> 
      </CdtTrfTxInf> 
     </PmtInf> 

     <PmtInf> 
      <things>f</things> <!--here there might be other nested tags inside <things></things>--> 
      <things>g</things> <!--here there might be other nested tags inside <things></things>--> 

      <CdtTrfTxInf> 
       <!-- other nested tags here --> 
      </CdtTrfTxInf> 
     </PmtInf> 

     <PmtInf> 
      <things>f</things> <!--here there might be other nested tags inside <things></things>--> 
      <things>g</things> <!--here there might be other nested tags inside <things></things>--> 

      <CdtTrfTxInf> 
       <!-- other nested tags here --> 
      </CdtTrfTxInf> 
     </PmtInf> 
    </CstmrCdtTrfInitn> 
</Document>  

現在,給這個結構,我要處理的部分如下:

如果存在有兩個或兩個以上<PmtInf>標籤相同:

<things>d</things> <!--here there might be other nested tags inside <things></things>--> 
<things>e</things> <!--here there might be other nested tags inside <things></things>--> 

我想整個<CdtTrfTxInf></CdtTrfTxInf>移至第一<PmtInf></PmtInf>和刪除整個<PmtInf></PmtInf>我已採取<CdtTrfTxInf></CdtTrfTxInf>從。有點模糊吧?這裏有一個例子:

<Document> 
    <CstmrCdtTrfInitn> 
     <GrpHdr> 
      <other_tags>a</other_tags> <!--here there might be other nested tags inside <other_tags></other_tags>--> 
      <other_tags>b</other_tags> <!--here there might be other nested tags inside <other_tags></other_tags>--> 
      <other_tags>c</other_tags> <!--here there might be other nested tags inside <other_tags></other_tags>--> 
     </GrpHdr> 

     <PmtInf> 
      <things>d</things> <!--here there might be other nested tags inside <things></things>--> 
      <things>e</things> <!--here there might be other nested tags inside <things></things>--> 

      <CdtTrfTxInf> 
       <!-- other nested tags here --> 
      </CdtTrfTxInf> 
     </PmtInf> 

     <PmtInf> 
      <things>f</things> <!--here there might be other nested tags inside <things></things>--> 
      <things>g</things> <!--here there might be other nested tags inside <things></things>--> 

      <CdtTrfTxInf> 
       <!-- other nested tags here --> 
      </CdtTrfTxInf> 
      <CdtTrfTxInf> 
       <!-- other nested tags here --> 
      </CdtTrfTxInf> 
     </PmtInf> 
    </CstmrCdtTrfInitn> 
</Document> 

正如你可以看到,近兩年<PmtInf></PmtInf>標籤現在變成了單一的一個(因爲<things></matched>)和<CdtTrfTxInf></CdtTrfTxInf>被複制。

現在,我想以任何可能的方式做到這一點(lxmlxml.etree,xslt等)。起初,我想過使用一些RegEx來做到這一點,但它可能會變得有點醜陋。然後,我想我可能可以使用一些字符串操作,但我無法想出如何做到這一點。

如果XML文件的平均大小約爲2k行,有人可以告訴我哪種方法是最優雅/最有效的方法嗎?一個例子也會受到讚賞。

對於completness的緣故,我會定義將一個字符串返回完整的XML內容的功能:

def get_xml_from(some_file): 
    with open(some_file) as xml_file: 
     content = xml_file.read() 

    return content 


def modify_xml(some_file): 
    content_of_xml = get_xml_from(some_file) 

    # here I should be able to process the XML file 

    return processed_xml 

我不找人做這對我來說,卻要求想法是什麼是實現這一目標的最佳途徑。

+3

甚至不嘗試使用'regex'路徑,'XML'不是常規語言。 「沒有XML模塊」背後的原因是什麼? – DeepSpace

+0

@DeepSpace XML是其他文件處理的結果,我沒有爲此使用XML模塊。這不是一個強制性的要求,但據我研究'lxml'和'xml.etree'我沒有成功找到一個乾淨的方式來做到這一點 –

回答

1

我不會給你你想要的代碼。相反,我會說你如何去做你想做的事。

首先你要先讀你的xml。所以我會用xml.etree.ElementTree

import xml.etree.ElementTree as ET 
root = ET.fromstring(country_data_as_string) 

這之後我會忽略你不使用樹的部分,只是findCstmrCdtTrfInitn。 由於您只想與PmtInf一起工作,您想要findall

pmt_infs = root.find('.//CstmrCdtTrfInitn').findall('PmtInf') 

在這之後要執行你的算法*對你的數據移動項目。 我只是刪除第一個孩子,如果節點有一個。

nodes = [] 
for node in pmt_infs: 
    children = list(node) 
    if children: 
     node.remove(children[0]) 
     nodes.append(children[0]) 

現在,我們擁有所有的節點,你將它們添加到第一pmt_infs

pmt_infs[0].extend(nodes) 

*你要改變第三代碼塊要如何將您的節點,當你從V1改變了你的算法,你的問題的V3。

相關問題