Merging two XML source documents with XSLT
XML file one could have 1000 - 6000 forms; XML file two could have one to 100 or more. I want to replace any identical form in file one with file two. If it exists in file 2 but not in file one I want to add it to file 1. After the files are merged I want to run it against my XSLT. I am using a 2.0 stylesheet and a Saxon parser.
File 1:
<Forms> <Form name="fred" date="10/01/2008"/> <Form name="barney" date="12/31/2009"/> <Form name="wilma" date="12/31/2010"/> </Forms>
File 2:
<Forms> <Form name="barney" date="01/31/2010"/> <Form name="betty" date="6/31/2009"/> </Forms>
Merged file should look like:
<Forms> <Form name="fred" date="10/01/2008"/> <Form name="barney" date="01/31/2010"/> <Form name="wilma" date="12/31/2010"/> <Form开发者_StackOverflow name="betty" date="6/31/2009"/> </Forms>
If maintaining document order is not a priority:
<xsl:variable name="forms1" select="document('forms1.xml')/Forms/Form" />
<xsl:variable name="forms2" select="document('forms2.xml')/Forms/Form" />
<xsl:variable name="merged" select="
$forms1[not(@name = $forms2/@name)] | $forms2
" />
<xsl:template match="/">
<xsl:apply-templates select="$merged" />
</xsl:template>
<xsl:template match="Form">
<!-- for the sake of the example; you can use a more specialized template -->
<xsl:copy-of select="." />
</xsl:template>
If maintaining document order is a priority for whatever reason…
<xsl:template match="/">
<!-- check values of file 1 sequentially, and replace them if needed -->
<xsl:for-each select="$forms1">
<xsl:variable name="this" select="." />
<xsl:variable name="newer" select="$forms2[@name = $this/@name]" />
<xsl:choose>
<xsl:when test="$newer">
<xsl:apply-templates select="$newer" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$this" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<!-- append any values from file 2 that are not in file 1 -->
<xsl:apply-templates select="$forms2[not(@name = $forms1/@name)]" />
</xsl:template>
精彩评论