Using xsl:evaluate and the path() function to merge data from two documents with the same structure
On Stackoverflow there was a question to merge two documents with the same XML structure by copying text data from elements in a secondary input document to empty elements in the main input. I think this can be nicely done by using the path() function on empty elements together with the xsl:evaluate instruction (that is new in XSLT 3.0) to simply select and copy the text data from the secondary input document
<xsl:template match="*[not(has-children())]">
<xsl:copy>
<div class="merged">
<xsl:evaluate context-item="$doc2" xpath="path() || '/text()'"></xsl:evaluate>
</div>
</xsl:copy>
</xsl:template>
Full gist is
The posted stylesheet works fine with Saxon 9.7 and later editions supporting xsl:evaluate (PE and EE) and with current versions of Altova XMLSpy/Raptor.
<xsl:template match="*[not(has-children())]">
<xsl:copy>
<div class="merged">
<xsl:evaluate context-item="$doc2" xpath="path() || '/text()'"></xsl:evaluate>
</div>
</xsl:copy>
</xsl:template>
Full gist is
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<root> | |
<content> | |
<text-block> | |
<descriptionHead> | |
Some description text for the text block head. | |
</descriptionHead> | |
<description> | |
Some description text block text. | |
</description> | |
</text-block> | |
<shortDescription> | |
<textHead> | |
Example text for the short description head. | |
</textHead> | |
<textBody> | |
Example text for the short description text body. | |
</textBody> | |
</shortDescription> | |
<longDescription> | |
<textHead> | |
Example text for the long description head. | |
</textHead> | |
<textBody> | |
Example text for the short description text body. | |
</textBody> | |
</longDescription> | |
</content> | |
</root> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<root> | |
<content> | |
<text-block> | |
<descriptionHead> | |
Some text 1. | |
</descriptionHead> | |
<description> | |
Some text 2. | |
</description> | |
</text-block> | |
<shortDescription> | |
<textHead></textHead> | |
<textBody></textBody> | |
</shortDescription> | |
<longDescription> | |
<textHead> | |
Some text 3. | |
</textHead> | |
<textBody></textBody> | |
</longDescription> | |
</content> | |
</root> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
xmlns:math="http://www.w3.org/2005/xpath-functions/math" | |
exclude-result-prefixes="xs math" | |
version="3.0"> | |
<xsl:param name="doc2-uri" as="xs:string" select="'doc2.xml'"/> | |
<xsl:param name="doc2" select="doc($doc2-uri)"/> | |
<xsl:mode on-no-match="shallow-copy"/> | |
<xsl:template match="*[not(has-children())]"> | |
<xsl:copy> | |
<div class="merged"> | |
<xsl:evaluate context-item="$doc2" xpath="path() || '/text()'"></xsl:evaluate> | |
</div> | |
</xsl:copy> | |
</xsl:template> | |
</xsl:stylesheet> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?><root> | |
<content> | |
<text-block> | |
<descriptionHead> | |
Some text 1. | |
</descriptionHead> | |
<description> | |
Some text 2. | |
</description> | |
</text-block> | |
<shortDescription> | |
<textHead><div class="merged"> | |
Example text for the short description head. | |
</div></textHead> | |
<textBody><div class="merged"> | |
Example text for the short description text body. | |
</div></textBody> | |
</shortDescription> | |
<longDescription> | |
<textHead> | |
Some text 3. | |
</textHead> | |
<textBody><div class="merged"> | |
Example text for the short description text body. | |
</div></textBody> | |
</longDescription> | |
</content> | |
</root> |
The posted stylesheet works fine with Saxon 9.7 and later editions supporting xsl:evaluate (PE and EE) and with current versions of Altova XMLSpy/Raptor.
Comments
Post a Comment