2016-07-17 17 views
1

私はPythonとrequestsライブラリを使用してPOSTリクエストをXMLファイルで送信しています。あなたが実際に機能によって生成されているproperty_name変数がある見ることができるように変数に格納されたXML文字列に変数を追加する

property_name = """<wfs:Property> 
    <wfs:Name>Adm2_NAME</wfs:Name> 
    <wfs:Value>fff</wfs:Value> 
</wfs:Property>""" 

xml = """<wfs:Transaction service="WFS" version="1.0.0" 
    xmlns:ogc="http://www.opengis.net/ogc" 
    xmlns:wfs="http://www.opengis.net/wfs"> 
    <wfs:Update typeName="geonode:tjk_nhr_shockriskscore"> 
    """ + property_name + """ 
    <ogc:Filter> 
     <ogc:FeatureId fid="tjk_nhr_shockriskscore.2"/> 
    </ogc:Filter> 
    </wfs:Update> 
</wfs:Transaction>""" 

:私のXMLファイルには、次のようになります。

すぐにXML文字列を連結して変数property_nameを手動で追加しました。しかし、私はこれらの変数の多くを持っているので、私は正しい位置にそれらを追加する方法を見つける必要があります。

これをPythonで行う正しい方法は何ですか?これを達成するためのライブラリーまたは推奨テクニックがありますか?

+1

'.format()'を使ってみましたか? –

+0

あなたのサーバーの 'XML'データパターンとは何ですか?私の考えは、 'property'定義のcosを使っていません。 '更新セクション 'の下に' Adm2_NAME fff'を使用してください。サーバーがあなたの 'property'を受け入れない、' invalid key error'を起こすかもしれません。コードにエラーはありませんが、サーバー側のパターンを宣言する必要があります。だから、おそらく '主キー'であり、 '不動産 'ではないかもしれない。 – dsgdfg

答えて

1

XSLTは、XMLファイルを変換して他のXMLの一部をメインXMLファイルに追加する特別な目的の言語です。 Pythonのサードパーティ製モジュールlxmlは、XSLT 1.0スクリプトを処理できます。 XSLTはdocument()関数を維持し、同じディレクトリまたはサブディレクトリ内のドキュメント間でクエリを実行できます。ただし、このアプローチを実行するには、文書全体の処理を処理するために、小さなXMLストリングをディスクまたはファイルに保存し、XSLTスクリプトに保存する必要があります。

もう1つの重要な要件は、小さいXML文字列がルートタグ<wfs:Property xmlns:wfs="http://www.opengis.net/wfs">に名前空間を定義して、ファイルに出力する前に連結する必要があることです。他のXML文字列をXSLTに追加するには、プロパティルーチンに従って、指定した親ノードに一致するxslテンプレートに<xsl:copy-of select="document('OtherXML.xml')">という行を追加します。

import lxml.etree as et 

# SAVE XML TO FILE 
nmsp = 'xmlns:wfs="http://www.opengis.net/wfs"' 
property_name = '''<wfs:Property {}> 
    <wfs:Name>Adm2_NAME</wfs:Name> 
    <wfs:Value>fff</wfs:Value> 
</wfs:Property>''' 
xmlfile = open('Property.xml','w') 
xmlfile.write(property_name.format(nmsp)) 
xmlfile.close() 

# SAVE XSL TO FILE 
xslstr = '''<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="wfs:Update"> 
    <xsl:copy> 
     <xsl:copy-of select="document('Property.xml')"/> 
     <xsl:apply-templates /> 
    </xsl:copy> 
    </xsl:template>   
</xsl:transform>''' 
xslfile = open('XSLTScript.xsl','w') 
xslfile.write(xslstr) 
xslfile.close() 

# PARSE MAIN XML STRING 
xml = '''<wfs:Transaction service="WFS" version="1.0.0" 
xmlns:ogc="http://www.opengis.net/ogc" 
xmlns:wfs="http://www.opengis.net/wfs"> 
<wfs:Update typeName="geonode:tjk_nhr_shockriskscore">   
    <ogc:Filter> 
    <ogc:FeatureId fid="tjk_nhr_shockriskscore.2"/> 
    </ogc:Filter> 
</wfs:Update> 
</wfs:Transaction>''' 
dom = et.fromstring(xml) 

# TRANSFORM XML 
xsl = et.parse('XSLTScript.xsl') 
transform = et.XSLT(xsl) 
newdom = transform(dom) 

print(newdom) 
# <?xml version="1.0"?> 
# <wfs:Transaction xmlns:ogc="http://www.opengis.net/ogc" 
# xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0"> 
# <wfs:Update> 
#  <wfs:Property> 
#  <wfs:Name>Adm2_NAME</wfs:Name> 
#  <wfs:Value>fff</wfs:Value> 
#  </wfs:Property> 
#  <ogc:Filter> 
#  <ogc:FeatureId fid="tjk_nhr_shockriskscore.2"/> 
#  </ogc:Filter> 
# </wfs:Update> 
# </wfs:Transaction> 

# OUTPUT FINAL XML 
xmlfile = open('Final.xml','wb') 
xmlfile.write(newdom) 
xmlfile.close() 

また、まだXSLTを使用して、あなたはdocument()またはディスクに個々の文字列を保存するための任意の必要性を回避することができます。この方法では、小さなXMLストリングをXSLTのテンプレートマッチに連結するだけです。

import lxml.etree as et 

# XML STRING 
property_name = '''<wfs:Property> 
    <wfs:Name>Adm2_NAME</wfs:Name> 
    <wfs:Value>fff</wfs:Value> 
</wfs:Property>''' 

# XSL STRING 
xslstr = '''<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="wfs:Update"> 
    <xsl:copy> 
     {} 
     <xsl:apply-templates /> 
    </xsl:copy> 
    </xsl:template>  
</xsl:transform>'''.format(property_name) 

# PARSE MAIN XML STRING 
xmlstr = '''<wfs:Transaction service="WFS" version="1.0.0" 
xmlns:ogc="http://www.opengis.net/ogc" 
xmlns:wfs="http://www.opengis.net/wfs"> 
<wfs:Update typeName="geonode:tjk_nhr_shockriskscore">   
    <ogc:Filter> 
    <ogc:FeatureId fid="tjk_nhr_shockriskscore.2"/> 
    </ogc:Filter> 
</wfs:Update> 
</wfs:Transaction>''' 
dom = et.fromstring(xmlstr) 

# TRANSFORM XML 
xsl = et.fromstring(xslstr) 
transform = et.XSLT(xsl) 
newdom = transform(dom) 

print(newdom) 
# <?xml version="1.0"?> 
# <wfs:Transaction xmlns:ogc="http://www.opengis.net/ogc" 
# xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0"> 
# <wfs:Update> 
#  <wfs:Property> 
#  <wfs:Name>Adm2_NAME</wfs:Name> 
#  <wfs:Value>fff</wfs:Value> 
#  </wfs:Property> 
#  <ogc:Filter> 
#  <ogc:FeatureId fid="tjk_nhr_shockriskscore.2"/> 
#  </ogc:Filter> 
# </wfs:Update> 
# </wfs:Transaction> 

# OUTPUT FINAL XML 
xmlfile = open('Final.xml','wb') 
xmlfile.write(newdom) 
xmlfile.close() 
+0

私はワークフローと少し混乱しています。なぜあなたは:PARSE MAIN XML STRING?また、実際には、最初のxmlに複数のproperty_nameを追加する必要があります。このコードは現在、property_nameが1つしかない場合に使用できます。右? – user1919

+0

また、#XSL STRINGにはXMLにはない要素が含まれています。これらすべての要素はどこから来たのでしょうか? – user1919

+1

最初のタイプのドキュメントアプローチでは、コピーラインまたは各プロパティを追加します( '' 2番目のオプション文字列のアプローチでは、 'format()'と同じ場所に他のプロパティを追加すると、複数の要素を取りますが、対応する '{0}、{1}、... 'を追加できます。 – Parfait

関連する問題