I am looking to combine the same attribute from two or more ancestor tags into the tag I am matching in my template.
Example input:
<tag1 indent="up2">
<tag2 indent="up1">
<tag3></tag3>
</tag2>
</tag1>
Example output:
<tag1 indent="up2">
<tag2 indent="up1">
<tag3 indent="up3"></tag3>
</tag2>
</tag1>
So basically, I am looking for child tags to inherit the indent from their ancestors- there could also be other levels(the number of levels could change). There could also be "down" tags.
What I thought about doing is replacing the "up" with a "+" and then "down" with a "-", doing the mathematical operation and then putting it in.
How about something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[@indent]">
<xsl:param name="prev-indent" select="0"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()">
<xsl:with-param name="prev-indent" select="translate($prev-indent, 'dupown', '-') + translate(@indent, 'dupown', '-')" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:param name="prev-indent" select="0"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="indent">
<xsl:choose>
<xsl:when test="$prev-indent < 0">
<xsl:text>down</xsl:text>
<xsl:value-of select="-$prev-indent" />
</xsl:when>
<xsl:otherwise>
<xsl:text>up</xsl:text>
<xsl:value-of select="$prev-indent" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Since you're using XSLT 2.0, you could simplify this to:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(@indent)]">
<xsl:variable name="indent" select="sum(ancestor::*/number(translate(@indent, 'dupown', '-')))" />
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="indent" select="concat(if ($indent lt 0) then 'down' else 'up', abs($indent))"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.