0

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

如何根据根/参考/值进行分组并在输出中添加分组序列号?

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

先感谢您。

4

2 回答 2

1

这个 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>
于 2012-09-11T07:54:44.600 回答
1

这与您之前在 xslt 1.0 中对 xml 节点进行分组的问题非常相似

但是,在这种情况下,您确实希望匹配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>
于 2012-09-11T08:03:56.700 回答