鉴于此源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>
我需要汇总共享公共InvID
的所有项目,为该组源元素输出单个Data
元素,然后将所有row
元素值输出到子元素中那个Data
元素(Value
)。
可以在XPath 1.0中完成吗?
答案 0 :(得分:1)
正如我在评论中建议的那样,您正在寻找的技术称为 Muenchian分组。这可以通过定义将相关节点组合在一起的键,然后使用generate-id
或count
的技巧构建一个由一个&#34;代表&#34组成的节点集。 ;每个组的节点。在您的情况下,由于您要组合在一起的节点具有不同的名称,因此您必须对匹配模式更具创造性,但原则是相同的:
<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>