2016-04-10 5 views
0

XML文書から、1つのノードをすべての親ノードでファイルに保存したいが、子ノードは付けない。たとえば、次のXMLのために:<Document>ノード用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> 

期待される出力は次のようになります。

<?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プロセッサが組み込まれています。 (そのスクリプト整形式のXML文書でも十分にKML宣言されていない名前空間を扱うことができるである)さらに、XSLT:

XSLTスクリプト(の.xslはPythonでロードされるように、他の言語への移植も、セーブ)

<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

関連する問題