【问题标题】:Concatenating according interconnected attributes根据相互关联的属性进行连接
【发布时间】:2020-01-21 14:28:55
【问题描述】:

需要以两种并行方式连接 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 代码部分解决了第二个选项。它根据级别划分,但级别后缀的计算与层次结构的计算无关。不显示底部(较低)级别。输出电平的顺序也与期望的相反。

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>

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

    试试这个

    <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>
    

    请参阅 https://xsltfiddle.liberty-development.net/bFWRAoS/2 的转换

    【讨论】:

    • 它是更复杂任务的一部分,分为多个部分。我将发布附加条件。希望它们可以很好地集成到您的代码中。
    猜你喜欢
    • 2018-07-27
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    相关资源
    最近更新 更多