Reputation: 13
I want to replace the file path with the predefined variables.
Source for path variables (only two examples - in the desired result it would be much more):
<xsl:variable name='fileA'>
<xsl:text>C:\\example\\fileA.xml</xsl:text>
</xsl:variable>
<xsl:variable name='fileB'>
<xsl:text>C:\\example\\fileB.xml</xsl:text>
</xsl:variable>
Source for tags with paths:
<topic insetPath="C:\\example\\fileA.xml" flowTag="title"/>
<topic insetPath="C:\\example\\fileB.xml" flowTag="text"/>
Desired XML output:
<topic flowTag="title"><xsl:attribute name="insetPath"><xsl:value-of select="$fileA"/></xsl:attribute></topic>
<topic flowTag="text"><xsl:attribute name="insetPath"><xsl:value-of select="$fileB"/></xsl:attribute>
My variables.xsl looks like this:
<xsl:stylesheet>
<xsl:variable name='fileA'>
<xsl:text>C:\\example\\fileA.xml</xsl:text>
</xsl:variable>
<xsl:variable name='fileB'>
<xsl:text>C:\\example\\fileB.xml</xsl:text>
</xsl:variable>
</xsl:stylesheet>
Upvotes: 1
Views: 125
Reputation: 16156
I'm not sure you should use (pure) XSLT for this, since XSLT lacks containers that allow good runtime complexity, but the code is simple enough:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Load the variables from a separate XML file.
Note that this "xsl:" refers to the alias in *this* document, regardless of what alias, if any, is used in varaibles.xml -->
<xsl:variable name="variables" select="document('variables.xml')/*/xsl:variable/xsl:text/text()"/>
<!-- Simple modification of the identity transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<!-- Must emit attributes first, then elements afterwards. Thus, WET. -->
<xsl:apply-templates select="@*[not(.=$variables)]"/>
<xsl:for-each select="@*[.=$variables]">
<xsl:variable name="attr" select="string(.)"/>
<!-- Outputting XSLT itself is slightly painful -->
<xsl:element namespace="http://www.w3.org/1999/XSL/Transform" name="attribute">
<xsl:attribute name="name">
<xsl:value-of select="name()"/>
</xsl:attribute>
<xsl:element namespace="http://www.w3.org/1999/XSL/Transform" name="value-of">
<xsl:attribute name="select">
<xsl:text>$</xsl:text>
<!-- go up from the text() node, to the xsl:text element, to the xsl:variable element -->
<xsl:value-of select="$variables[.=$attr]/../../@name"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0