Apollo102
Apollo102

Reputation: 13

Replace content with XSLT by variable

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

Answers (1)

o11c
o11c

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

Related Questions