0

鉴于此源 XML:

<output>
   <report>
      <C01>
         <InvID>001</InvID>
         <Daily>
            <row id="0000">1</row>
            <row id="0001">2</row>
            <row id="0002">5</row>
            <row id="0003">4</row>
         </Daily>
      </C01>
      <C02>
         <InvID>002</InvID>
         <Daily>
            <row id="0000">4</row>
            <row id="0001">3</row>
            <row id="0002">2</row>
            <row id="0003">5</row>
         </Daily>
      </C02>
      <C03>
         <InvID>001</InvID>
         <Daily>
            <row id="0000">3</row>
            <row id="0001">7</row>
            <row id="0002">2</row>
            <row id="0003">4</row>
         </Daily>
      </C03>
   <report>
<output>

我怎样才能产生这个输出:

<Data invID=001>
   <Value>1</Value>
   <Value>2</Value>
   <Value>5</Value>
   <Value>4</Value>
   <Value>3</Value>
   <Value>7</Value>
   <Value>2</Value>
   <Value>4</Value>
</Data>
<Data invID=002>
   <Value>4</Value>
   <Value>3</Value>
   <Value>2</Value>
   <Value>5</Value>
</Data>

我一直在尝试使用这样的东西作为基础,但感觉完全不对:

<xsl:template match="output/report">
   <xsl:for-each select="*[starts-with(name(), 'C') and InvID != '']">
      <xsl:sort select="InvID" />
      <xsl:element name="Data">
         <xsl:attribute name="invID">
            <xsl:value-of select="InvID" />
         </xsl:attribute>
      </xsl:element>
   </xsl:for-each>
</xsl:template>

我需要聚合所有共享一个 common 的项目,为该组源元素InvID输出一个Data元素,然后将它们的所有row元素值输出到该元素的子Data元素 ( Value)。

这可以在 XPath 1.0 中完成吗?

4

1 回答 1

1

正如我在评论中建议的那样,您正在寻找的技术称为Muenchian grouping。这通过定义一个将相关节点组合在一起的generate-id来工作,然后使用技巧或count构造一个节点集,该节点集由每个组的一个“代表”节点组成。在您的情况下,由于您要组合在一起的节点具有不同的名称,因此您必须在匹配模式方面更具创意,但原则是相同的:

<xsl:key name="groupByInv" match="*[InvID]" use="InvID" />

在这里,我对任何有InvID孩子的元素(无论名称)感兴趣,我想根据InvID值将它们组合在一起。现在实际的分组很简单:

<xsl:template match="output/report">
  <xsl:for-each select="*[InvID][generate-id() =
         generate-id(key('groupByInv', InvID)[1])]">
    <Data invID="{InvID}">
      <!-- process all the rows under all the elements in the current group -->
      <xsl:apply-templates select="key('groupByInv', InvID)/Daily/row" />
    </Data>
  </xsl:for-each>
</xsl:template>

<xsl:template match="row">
  <Value><xsl:value-of select="."/></Value>
</xsl:template>
于 2015-02-10T19:10:00.123 回答