使用xsl

时间:2015-05-14 20:19:00

标签: xslt xslt-1.0

我想使用xsl合并节点列表中的不同值节点。每当有不同的值紫罗兰时,它就会创建一个新标记。

输入:

 <PAGE>
     <T>1</T>
     <T>2</T>
     <T>3</T>
     <T>2</T>
     <T>1</T>
     <T>3</T>
     <T>3</T>
 </PAGE>

 Output:
  <PAGE>
      <T>1,2,3</T>
      <T>2,1,3</T>
      <T>3</T>
 </PAGE>

假设前三个节点的值为1,2和3,第四个节点的值为2,那么我们必须合并前三个,因为所有值都是唯一的。然后下一次合并将从第四个节点开始。现在假设第五个节点再次具有值2.然后输出只有第四个节点将存在,因为下一个节点值相同。同样明智的是,只要值是唯一的,我就必须继续合并节点。例如,如果节点值流是1,2,2,3,4,1,1,3,3,则输出将为12,2341,13,3.IN。合并节点的唯一值可以存在。 请建议我使用XSL

1 个答案:

答案 0 :(得分:0)

以下样式表:

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="PAGE">
    <xsl:copy>
        <xsl:apply-templates select="T[1]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="T">
    <xsl:param name="prev-string" select="','"/>
    <xsl:variable name="next-string" select="concat($prev-string, ., ',')" />
    <xsl:variable name="next-node" select="following-sibling::T[1]" />
    <xsl:choose>
        <xsl:when test="contains($next-string, concat(',', $next-node, ',')) or not($next-node)">
            <!-- End of chain: create an element and output the accumulated string ... -->
            <xsl:copy>
                <xsl:value-of select="substring($next-string, 2, string-length($next-string) - 2)"/>
            </xsl:copy> 
            <!-- ... and start a new chain -->
            <xsl:apply-templates select="$next-node"/>
        </xsl:when>
        <xsl:otherwise>
            <!-- Continue the current chain: add the current value to the accumulated values -->
            <xsl:apply-templates select="$next-node">
                <xsl:with-param name="prev-string" select="$next-string"/>
            </xsl:apply-templates>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入时,将返回:

<?xml version="1.0" encoding="UTF-8"?>
<PAGE>
   <T>1,2,3</T>
   <T>2,1,3</T>
   <T>3</T>
</PAGE>

注意

  • 假设值不包含分隔字符 (本例中为逗号);
  • 虽然这会使用tail-recursion(部分地,无论如何),但是大型文档可以轻松地将处理器发送到堆栈溢出。