inserting an element in an xml document using its xpath
Here is the issue, I have an incomplete document (docA) and would like to insert some xml element at some specific position defined by some xpath string (in a doc elementList) to get a complete document (docB).
So basically, given the document docA:
<document>
<information type="person">
&l开发者_StackOverflow中文版t;id>string</id>
<customer>
<customerID>abc</customerID>
<externalID>2</externalID>
<person>
<gender>M</gender>
<firstName>John</firstName>
<!-- here should be a middle name -->
<lastName>Doe</lastName>
<birthdate>2011-05-05</birthdate>
</person>
<!-- more elements... -->
</customer>
<!-- more elements... -->
</information >
</document>
and the elementList:
<newElementSet>
<element>
<name>Middle Name</name>
<path>/document/information/customer/person/middleName</path>
<value>Fitzgerald</value>
</element>
<!-- some more element could go there -->
</newElementSet>
the output document should be:
<document>
<information type="private">
<id>string</id>
<customer>
<customerID>abc</customerID>
<externalID>2</externalID>
<person>
<gender>M</gender>
<firstName>John</firstName>
<middleName>Fitzgerald</middleName>
<lastName>Doe</lastName>
<birthdate>2011-05-05</birthdate>
</person>
<!-- more elements... -->
</customer>
<!-- more elements... -->
</information >
</document>
Any way this could be done in xslt? I tried using Xquery but it doesn't seem to be possible (cannot use the Xquery update as it's not yet supported).
Edit: I just want to precise that this is just a simplified presentation of the problem. In reality, we have more element to add and there values are actually going to be taken from user inputs...
This can be done very easily, you only have to change the "elementList" document a little bit -- to this XML document:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="person/firstName">
<xsl:call-template name="identity"/>
<middleName>Fitzgerald</middleName>
</xsl:template>
</xsl:stylesheet>
Then just apply this transformation to the provided source XML document:
<document>
<information type="person">
<id>string</id>
<customer>
<customerID>abc</customerID>
<externalID>2</externalID>
<person>
<gender>M</gender>
<firstName>John</firstName>
<!-- here should be a middle name -->
<lastName>Doe</lastName>
<birthdate>2011-05-05</birthdate>
</person>
<!-- more elements... -->
</customer>
<!-- more elements... -->
</information >
</document>
and the wanted, correct result is produced:
<document>
<information type="person">
<id>string</id>
<customer>
<customerID>abc</customerID>
<externalID>2</externalID>
<person>
<gender>M</gender>
<firstName>John</firstName>
<middleName>Fitzgerald</middleName><!-- here should be a middle name -->
<lastName>Doe</lastName>
<birthdate>2011-05-05</birthdate>
</person><!-- more elements... -->
</customer><!-- more elements... -->
</information>
</document>
Discussion:
This solution is surprizingly simpler than trying to implement any kind of dynamic evaluation.
The XML document specifying the wanted changes is compact.
The logic is straight and not convoluted as with any partial dynamic evaluation implementation.
No additional XSLT document is necessary.
This is a simple and easy to implement, understand and maintain solution.
精彩评论