【问题标题】:How to do Grouping of NodeItems in xslt 1.0?如何在 xslt 1.0 中对 NodeItem 进行分组?
【发布时间】:2012-09-11 06:41:00
【问题描述】:

输入xml:

<Root>
    <RootHeader>Header</RootHeader>
    <Reference>
        <name>RefName</name>
        <value>Header001</value>
    </Reference>

    <NodeNumber>1</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>100</value>
    </Reference>

    <NodeNumber>2</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>101</value>
    </Reference>

    <NodeNumber>3</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>101</value>
    </Reference>

    <NodeNumber>4</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>100</value>
    </Reference>

    <NodeNumber>5</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>102</value>
    </Reference>
</Root>

预期输出:

<Root>
    <RootHeader>Header</RootHeader>
    <Reference>
        <name>RefName</name>
        <value>Header001</value>
    </Reference>

    <GroupingSequenceNumber>1</GroupingSequenceNumber>
    <NodeNumber>1</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>100</value>
    </Reference>

    <GroupingSequenceNumber>1</GroupingSequenceNumber>
    <NodeNumber>2</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>101</value>
    </Reference>

    <GroupingSequenceNumber>2</GroupingSequenceNumber>
    <NodeNumber>3</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>100</value>
    </Reference>

    <GroupingSequenceNumber>3</GroupingSequenceNumber>
    <NodeNumber>4</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>100</value>
    </Reference>

    <GroupingSequenceNumber>1</GroupingSequenceNumber>
    <NodeNumber>5</NodeNumber>
    <Reference>
        <name>RefName</name>
        <value>102</value>
    </Reference>
</Root>

如何根据 Root/Reference/Value 进行分组并在输出中添加 Grouping Sequence Number?

在分组中应排除标题中的引用。意味着分组应该在出现 NodeNumber 之后开始。

在此先感谢您。

【问题讨论】:

  • 您提供了一个用例,这是一个好的开始。但我还是不明白你的要求。什么是分组,分组条件是什么? GroupingSequenceNumber 的意义是什么? Reference 节点是否应该计入其先前的兄弟 NodeNumber 节点?
  • 你好..让我根据输入样本解释一下,根/参考/值包含值 100,101,102...所以应该对这个值应用分组..并且 GroupingSequenceNumber 将包含序列号,比如说对于 Root/Reference/Value = 100,GroupingSequenceNumber = 1,2,3[occurrences of 100]
  • 您的解释与提供的示例不符。在输入中,节点 1 和 4 的值为 100。但在您提供的输出中,它们甚至没有组合在一起。
  • 感谢您的指正..我已经更正了预期的输出
  • 这是 Muenchian 分组的直接案例。 StackOverflow 上有数百个问题,这些问题只是这个问题的轻微变化。当然,很快会有人给你一个具体的答案,但是搜索和阅读以前的问题会对你有所帮助。搜索 Muenchian 或“xslt 分组”。

标签: xml xslt xslt-1.0


【解决方案1】:

这和你之前Grouping of xml nodes in xslt 1.0的问题很相似

但在这种情况下,您确实希望匹配 NodeNumber 元素,并通过查看 Reference 元素后面的值来计算它们。

<xsl:variable name="Ref" select="following-sibling::Reference[1]/value"/>
<GroupingSequenceNumber>
   <xsl:number count="NodeNumber[following-sibling::Reference[1]/value = $Ref]"/>
</GroupingSequenceNumber>

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="NodeNumber">
      <xsl:variable name="Ref" select="following-sibling::Reference[1]/value"/>
      <GroupingSequenceNumber>
         <xsl:number count="NodeNumber[following-sibling::Reference[1]/value = $Ref]"/>
      </GroupingSequenceNumber>
      <xsl:copy-of select="."/>
   </xsl:template>

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

当应用于您的示例输入文档时,以下是输出

<Root>
   <RootHeader>Header</RootHeader>
   <Reference>
      <name>RefName</name>
      <value>Header001</value>
   </Reference>
   <GroupingSequenceNumber>1</GroupingSequenceNumber>
   <NodeNumber>1</NodeNumber>
   <Reference>
      <name>RefName</name>
      <value>100</value>
   </Reference>
   <GroupingSequenceNumber>1</GroupingSequenceNumber>
   <NodeNumber>2</NodeNumber>
   <Reference>
      <name>RefName</name>
      <value>101</value>
   </Reference>
   <GroupingSequenceNumber>2</GroupingSequenceNumber>
   <NodeNumber>3</NodeNumber>
   <Reference>
      <name>RefName</name>
      <value>101</value>
   </Reference>
   <GroupingSequenceNumber>2</GroupingSequenceNumber>
   <NodeNumber>4</NodeNumber>
   <Reference>
      <name>RefName</name>
      <value>100</value>
   </Reference>
   <GroupingSequenceNumber>1</GroupingSequenceNumber>
   <NodeNumber>5</NodeNumber>
   <Reference>
      <name>RefName</name>
      <value>102</value>
   </Reference>
</Root>

【讨论】:

    【解决方案2】:

    这个 XSLT 1.0 样式表...

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />
    
    <xsl:key name="kRefs" match="Reference[preceding-sibling::NodeNumber]" use="value" />
    
    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="/*">
      <xsl:copy>
        <xsl:apply-templates select="
          @* | node()[not(self::Reference[preceding-sibling::NodeNumber])][not(self::NodeNumber)]" />
        <xsl:for-each select="
            Reference[preceding-sibling::NodeNumber]
                     [generate-id() = generate-id(key('kRefs',value)[1])]">
           <xsl:comment>Start of group for value <xsl:value-of select="value" /></xsl:comment> 
           <xsl:apply-templates select="key('kRefs',value)" />            
           <xsl:comment>End of group</xsl:comment>   
        </xsl:for-each>               
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Reference[preceding-sibling::NodeNumber]" >
      <GroupingSequenceNumber><xsl:value-of select="position()" /></GroupingSequenceNumber>
      <xsl:copy-of select=".|preceding-sibling::NodeNumber[1]" />
    </xsl:template>
    
    </xsl:stylesheet>
    

    ...当应用于此输入时...

    <Root>
        <RootHeader>Header</RootHeader>
        <Reference>
            <name>RefName</name>
            <value>Header001</value>
        </Reference>
    
        <NodeNumber>1</NodeNumber>
        <Reference>
            <name>RefName</name>
            <value>100</value>
        </Reference>
    
        <NodeNumber>2</NodeNumber>
        <Reference>
            <name>RefName</name>
            <value>101</value>
        </Reference>
    
        <NodeNumber>3</NodeNumber>
        <Reference>
            <name>RefName</name>
            <value>101</value>
        </Reference>
    
        <NodeNumber>4</NodeNumber>
        <Reference>
            <name>RefName</name>
            <value>100</value>
        </Reference>
    
        <NodeNumber>5</NodeNumber>
        <Reference>
            <name>RefName</name>
            <value>102</value>
        </Reference>
    </Root> 
    

    ...产量...

    <Root>
      <RootHeader>Header</RootHeader>
      <Reference>
        <name>RefName</name>
        <value>Header001</value>
      </Reference>
      <!--Start of group for value 100-->
      <GroupingSequenceNumber>1</GroupingSequenceNumber>
      <NodeNumber>1</NodeNumber>
      <Reference>
        <name>RefName</name>
        <value>100</value>
      </Reference>
      <GroupingSequenceNumber>2</GroupingSequenceNumber>
      <NodeNumber>4</NodeNumber>
      <Reference>
        <name>RefName</name>
        <value>100</value>
      </Reference>
      <!--End of group-->
      <!--Start of group for value 101-->
      <GroupingSequenceNumber>1</GroupingSequenceNumber>
      <NodeNumber>2</NodeNumber>
      <Reference>
        <name>RefName</name>
        <value>101</value>
      </Reference>
      <GroupingSequenceNumber>2</GroupingSequenceNumber>
      <NodeNumber>3</NodeNumber>
      <Reference>
        <name>RefName</name>
        <value>101</value>
      </Reference>
      <!--End of group-->
      <!--Start of group for value 102-->
      <GroupingSequenceNumber>1</GroupingSequenceNumber>
      <NodeNumber>5</NodeNumber>
      <Reference>
        <name>RefName</name>
        <value>102</value>
      </Reference>
      <!--End of group-->
    </Root>
    

    【讨论】:

      猜你喜欢
      • 2016-01-25
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      相关资源
      最近更新 更多