Consider XSLT, the special purpose language to transform XML files, to append parts of other XMLs into main XML file. Python's third-party module, lxml, can process XSLT 1.0 scripts. XSLT maintains the document() function, allowing querying across documents in same or sub directory. However, in order to run this approach, you must save the smaller XML strings to disk or file as well as XSLT script to handle the across document processing.
Another important requirement is the smaller XML strings must define its namespace in root tag <wfs:Property xmlns:wfs="http://www.opengis.net/wfs"> so concatenate that prior to output to file. To add other XML strings turned files in the XSLT, follow the property routine and add a line <xsl:copy-of select="document('OtherXML.xml')"> in xsl template matched to specified parent node.
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()
Alternatively, still using XSLT, you can bypass any need for document() or saving individual strings to disk. In this approach, you simply concatenate the smaller XML strings to the template match of 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()
.format()?XMLdata pattern. My idea don't usepropertydefinition cos got a update. Use<wfs:Name>Adm2_NAME</wfs:Name> <wfs:Value>fff</wfs:Value>underUpdate section. Maybe server not accepting yourproperty,raise invalid key error. Your code haven't any error but need declare server side pattern. So name maybeprimary keyand not aproperty.