根据相互关联的属性连接
Concatenating according interconnected attributes
需要以两种并行方式连接 3-x 级父子关系。
1 - 全级串联输出
2 - 根据级别划分输出
源代码
<A>
<X id="top" text="first" text2="*"/>
<X id="middle" id-parent="top" text="second" text2="**"/>
<X id="bottom" id-parent='middle"' text="third" text2="***"/>
</A>
当前的 XSLT 代码部分解决了第二个 option.It 根据级别划分的问题,但是级别后缀的计算与层次结构的计算无关。不显示底部(较低)级别。此外,输出级别的顺序与所需顺序相反。
xslt转换
<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:key name="ref" match="X" use="@id"/>
<xsl:template match="X">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('ref', @id-parent)" mode="att"/>
</xsl:copy>
</xsl:template>
<xsl:template match="X" mode="att">
<xsl:param name="pos" select="count(@*) + 1"/>
<xsl:attribute name="level-{$pos}">
<xsl:value-of select="concat(@text,' ', '| ', @text2)"/>
</xsl:attribute>
<xsl:apply-templates select="key('ref', @id-parent)" mode="att">
<xsl:with-param name="pos" select="$pos + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
互联scheme
https://xsltfiddle.liberty-development.net/bFWRAoS/1
期望输出
<A> <!-- KIND OF-->
<X id="top" text="first" text2="*" chain-text="first *" level-1="first | *" /> <!-- however, this upper level may remain as in the base source and don't be changed -->
<X id="middle" id-parent="top" text="second" text2="**" chain-text="first * | second **" level-1="first | *" level-2="second | **"/>
<X id="bottom" id-parent="middle" text="third" text2="**" chain-text="first * | second ** | third ***" level-1="first | *" level-2="second | **" level-3="third | ***"/>
</A>
试试这个
<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:key name="ref" match="X" use="@id"/>
<xsl:template match="X">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:variable name="Xs">
<xsl:call-template name="XATT">
<xsl:with-param name="currentX" select="."/>
<xsl:with-param name="X" select=".">
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$Xs[node()]">
<xsl:attribute name="chain-text">
<xsl:for-each select="$Xs/X">
<xsl:if test="position() ne 1"><xsl:text> | </xsl:text></xsl:if>
<xsl:value-of select="concat(@text, ' ', @text2)"/>
</xsl:for-each>
</xsl:attribute>
<xsl:for-each select="$Xs/X">
<xsl:attribute name="level-{position()}"><xsl:value-of select="concat(@text, ' | ', @text2)"/></xsl:attribute>
</xsl:for-each>
</xsl:if>
</xsl:copy>
</xsl:template>
<xsl:template name="XATT">
<xsl:param name="currentX"/>
<xsl:param name="X"/>
<xsl:choose>
<xsl:when test="$currentX/@id-parent">
<xsl:call-template name="XATT">
<xsl:with-param name="currentX" select="key('ref', $currentX/@id-parent)"/>
<xsl:with-param name="X">
<xsl:copy-of select="key('ref', $currentX/@id-parent)"/>
<xsl:copy-of select="$X"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$X"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
处的转换
需要以两种并行方式连接 3-x 级父子关系。
1 - 全级串联输出
2 - 根据级别划分输出
源代码
<A>
<X id="top" text="first" text2="*"/>
<X id="middle" id-parent="top" text="second" text2="**"/>
<X id="bottom" id-parent='middle"' text="third" text2="***"/>
</A>
当前的 XSLT 代码部分解决了第二个 option.It 根据级别划分的问题,但是级别后缀的计算与层次结构的计算无关。不显示底部(较低)级别。此外,输出级别的顺序与所需顺序相反。
xslt转换
<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:key name="ref" match="X" use="@id"/>
<xsl:template match="X">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('ref', @id-parent)" mode="att"/>
</xsl:copy>
</xsl:template>
<xsl:template match="X" mode="att">
<xsl:param name="pos" select="count(@*) + 1"/>
<xsl:attribute name="level-{$pos}">
<xsl:value-of select="concat(@text,' ', '| ', @text2)"/>
</xsl:attribute>
<xsl:apply-templates select="key('ref', @id-parent)" mode="att">
<xsl:with-param name="pos" select="$pos + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
互联scheme
https://xsltfiddle.liberty-development.net/bFWRAoS/1
期望输出
<A> <!-- KIND OF-->
<X id="top" text="first" text2="*" chain-text="first *" level-1="first | *" /> <!-- however, this upper level may remain as in the base source and don't be changed -->
<X id="middle" id-parent="top" text="second" text2="**" chain-text="first * | second **" level-1="first | *" level-2="second | **"/>
<X id="bottom" id-parent="middle" text="third" text2="**" chain-text="first * | second ** | third ***" level-1="first | *" level-2="second | **" level-3="third | ***"/>
</A>
试试这个
<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:key name="ref" match="X" use="@id"/>
<xsl:template match="X">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:variable name="Xs">
<xsl:call-template name="XATT">
<xsl:with-param name="currentX" select="."/>
<xsl:with-param name="X" select=".">
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$Xs[node()]">
<xsl:attribute name="chain-text">
<xsl:for-each select="$Xs/X">
<xsl:if test="position() ne 1"><xsl:text> | </xsl:text></xsl:if>
<xsl:value-of select="concat(@text, ' ', @text2)"/>
</xsl:for-each>
</xsl:attribute>
<xsl:for-each select="$Xs/X">
<xsl:attribute name="level-{position()}"><xsl:value-of select="concat(@text, ' | ', @text2)"/></xsl:attribute>
</xsl:for-each>
</xsl:if>
</xsl:copy>
</xsl:template>
<xsl:template name="XATT">
<xsl:param name="currentX"/>
<xsl:param name="X"/>
<xsl:choose>
<xsl:when test="$currentX/@id-parent">
<xsl:call-template name="XATT">
<xsl:with-param name="currentX" select="key('ref', $currentX/@id-parent)"/>
<xsl:with-param name="X">
<xsl:copy-of select="key('ref', $currentX/@id-parent)"/>
<xsl:copy-of select="$X"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$X"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
处的转换