2016-04-10 94 views
0

從XML文檔中,我想將一個節點保存到文件 - 包含所有父節點,但沒有任何子節點。例如,對於下面的XML:保存(打印)xml節點及其父母但沒有子女

<?xml version="1.0" encoding="UTF-8"?> 
<kml xmlns="http://earth.google.com/kml/2.1"> 
<Document id="myid"> 
    <name>ref.kml</name> 
    <Style id="normalState"> 
    <IconStyle><scale>1.0</scale><Icon><href>yt.png</href></Icon></IconStyle>  
    </Style> 
</Document> 
</kml> 

<Document>節點預計產量將是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<kml xmlns="http://earth.google.com/kml/2.1"> 
<Document id="myid"> 
</Document> 
</kml> 

到目前爲止,我只找到了迭代去除所有子元素的溶液中保存前。但由於我需要使用原始XML後,我必須複製整個文檔:

#!/usr/bin/env python 

import lxml.etree as ET # have to use [lxml] because [xml] doesn't support 'xml_declaration' 
import copy 

kml_file = ET.parse("myfile.kml") 
kml_copied = copy.deepcopy(kml_file) # .copy() is not enough, need .deepcopy() 
root = kml_copied.getroot() 
my_node = root[0] 
for child in my_node: 
    my_node.remove(child) 
print ET.tostring(kml_copied, xml_declaration=True, encoding='utf-8') 

有沒有更好的方法來做到這一點?至少避免對整個文檔進行深度拷貝......

回答

0

考慮XSLT,這是專門用於轉換XML文檔的專用聲明性語言。而Python的lxml模塊有一個內置的XSLT 1.0處理器。此外XSLT(其腳本是一個良好的XML文檔也可以充分地處理KML未申報命名空間):

XSLT腳本(另存爲在Python中加載的.xsl,也移植到其他語言)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:doc="http://earth.google.com/kml/2.1"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <!-- Identity Transform to copy entire document --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Empty Template to Remove Nodes --> 
    <xsl:template match="doc:Style|doc:name"/> 

</xsl:transform> 

的Python腳本

import lxml.etree as ET 

# LOAD XML AND XSL 
dom = ET.parse('Input.xml') 
xslt = ET.parse('XSLTScript.xsl') 

# TRANSFORM INPUT INTO DOM OBJECT 
transform = ET.XSLT(xslt) 
newdom = transform(dom) 

# OUTPUT DOM TO STRING 
tree_out = ET.tostring(newdom, 
         encoding='UTF-8', 
         pretty_print=True, 
         xml_declaration=True) 
print(tree_out.decode("utf-8")) 

# SAVE RESULTING XML 
xmlfile = open('Output.xml','wb') 
xmlfile.write(tree_out) 
xmlfile.close() 

輸出

<?xml version='1.0' encoding='UTF-8'?> 
<kml xmlns="http://earth.google.com/kml/2.1"> 
    <Document id="myid"/> 
</kml> 
+0

好吧,我認爲啓動XSLT機器這麼簡單的任務會有點矯枉過正:)但我會考慮它,謝謝你的回答! –

+0

請注意,除了刪除節點之外,還可以在同一個XSLT腳本中處理其他XML修改。你可以在Python中嵌入XSLT而不是外部文件。此外,文件可移植到其他語言和可執行文件(Java,PHP,C#,VBA,Saxon,Xalan)。當然,一個可擴展的答案!如果有幫助,請接受以確認解決方案。 – Parfait

相關問題