Skip to content Skip to sidebar Skip to footer

How To Apply More Then One Xsl-templates On One Xml Node

here is my problem: I have HTML Document with CSS Styles. I need to move these styles into the elements in the body and remove them from style tag. I made helper that makes xpath f

Solution 1:

Here is one way you could do it, by use of mode attributes, to apply each template one after another

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@class">
    <xsl:attribute name="style">
      <xsl:if test="@style">
        <xsl:value-of select="@style" />
        <xsl:text>;</xsl:text>
      </xsl:if>
      <xsl:apply-templates select="." mode="right-aligned" />
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="@style" />

  <xsl:template match="@class" mode="right-aligned">
    <xsl:if test="contains(.,'right-aligned')">
      <xsl:text>text-align: right !important;</xsl:text>
    </xsl:if>
    <xsl:apply-templates select="." mode="full-width" />
  </xsl:template>

  <xsl:template match="@class" mode="full-width">
    <xsl:if test="contains(.,'full-width')">
      <xsl:text>width: 100% !important; display: inline-block;</xsl:text>
    </xsl:if>
  </xsl:template>  
</xsl:stylesheet>

If you could use XSLT 2.0, you could simplify this by use of priorities, instead of modes, and xsl:next-match to find the next matching template with a lower priority.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@class" priority="10">
    <xsl:attribute name="style">
      <xsl:if test="@style">
        <xsl:value-of select="@style" />
        <xsl:text>;</xsl:text>
      </xsl:if>
      <xsl:next-match />
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="@style" />

  <xsl:template match="@class[contains(.,'right-aligned')]" priority="9">
    <xsl:text>text-align: right !important;</xsl:text>
    <xsl:next-match />
  </xsl:template>

  <xsl:template match="@class[contains(.,'full-width')]" priority="8">
    <xsl:text>width: 100% !important; display: inline-block;</xsl:text>
    <xsl:next-match />
   </xsl:template>  

  <xsl:template match="@class" /> <!-- Stop the built-in template applying -->
</xsl:stylesheet>

Post a Comment for "How To Apply More Then One Xsl-templates On One Xml Node"