我有一个像以下那样的XML。
<Doc>
<row>
<Col1>13820PKS-</Col1>
<Col6>01</Col6>
<Col9>1507462800</Col9>
<Col12>15074628</Col12>
<Col14>4</Col14>
</row>
<row>
<Col1>13820PKS-</Col1>
<Col6>01</Col6>
<Col9>1507462800</Col9>
<Col12>15074629</Col12>
<Col14>5</Col14>
</row>
<row>
<Col1>13820PKS-</Col1>
<Col6>01</Col6>
<Col9>1808502801</Col9>
<Col12>18085021</Col12>
<Col14>1</Col14>
</row>
<row>
<Col1>13820PKS-</Col1>
<Col6>02</Col6>
<Col9>2710004100</Col9>
<Col12>2710004100</Col12>
<Col14>1</Col14>
</row>
</Doc>
该文件实际上有超过2000行。 最终结果应该是
<Doc>
<ListID id="01">
<MainArt>
<ItemCode>13820PKS-</ItemCode>
<List>
<SubArt>
<ItemCode>1507462800</ItemCode>
<SubArtList>
<row>
<ItemCode>15074628</ItemCode>
<Quantity>4</Quantity>
</row>
<row>
<ItemCode>15074629</ItemCode>
<Quantity>5</Quantity>
</row>
</SubArtList>
</SubArt>
<SubArt>
<ItemCode>1808502801</ItemCode>
<SubArtList>
<row>
<ItemCode>18085021</ItemCode>
<Quantity>1</Quantity>
</row>
</SubArtList>
</SubArt>
</List>
</MainArt>
</ListID>
<ListID id="02">
<MainArt>
<ItemCode>13820PKS-</ItemCode>
<List>
<SubArt>
<ItemCode>2710004100</ItemCode>
<SubArtList>
<row>
<ItemCode>2710004100</ItemCode>
<Quantity>1</Quantity>
</row>
</SubArtList>
</SubArt>
</List>
</MainArt>
</ListID>
</Doc>
我仍在学习阶段,并没有真正掌握模板的技能。我尝试使用递归for-each循环,但这也没有用。 任何帮助将不胜感激。感谢
答案 0 :(得分:0)
通过三个级别的多重分组,您自己并不容易!但这就是你做的......
首先,您要按最高级别的 Col6 元素进行分组,因此您可以通过 Col6定义一个键来查找行元素价值。
<xsl:key name="Col6" match="row" use="Col6"/>
因此,对于给定值,该键将返回 Col6 元素等于该值的所有行元素。
现在,为了获得'不同' Col6 值,您会看到所有行元素,但只选择首先出现的行元素。 Col6 键的组。这样就完成了,
<xsl:apply-templates
select="row[generate-id() = generate-id(key('Col6', Col6)[1])]"
mode="Col6" />
(注意在这里使用模式,因为最终的XSLT将有多个匹配行元素的模板,因此您需要区分它们。)
现在,在匹配 Col6 的行元素的模板中,您需要按 Col1 元素进行分组。这是一个稍微复杂的地方,因为您需要定义一个键,它是 Col6 和 Col1 元素的组合。 (允许两个 Col1 元素可能具有不同的 Col6 值)
<xsl:key name="Col1" match="row" use="concat(Col6, '|', Col1)"/>
请注意使用管道|
字符来分隔值。这可以是任何字符,只要它不会出现在 Col6 或 Col1
然后在当前的 Col6 中获取不同的 Col1 元素,你会这样做
<xsl:apply-templates
select="key('Col6', Col6)
[generate-id() = generate-id(key('Col1', concat(Col6, '|', Col1))[1])]"
mode="Col1" />
最后,对于 Col9 元素,您将拥有一个三重连接键。
<xsl:key name="Col9" match="row" use="concat(Col6, '|', Col1, '|', Col9)"/>
可以类似的方式使用它来获取当前 Col1 中的所有 Col9 元素。
完全放弃,给出以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="Col6" match="row" use="Col6"/>
<xsl:key name="Col1" match="row" use="concat(Col6, '|', Col1)"/>
<xsl:key name="Col9" match="row" use="concat(Col6, '|', Col1, '|', Col9)"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="row[generate-id() = generate-id(key('Col6', Col6)[1])]" mode="Col6" />
</xsl:copy>
</xsl:template>
<xsl:template match="row" mode="Col6">
<ListID id="{Col6}">
<xsl:apply-templates select="key('Col6', Col6)[generate-id() = generate-id(key('Col1', concat(Col6, '|', Col1))[1])]" mode="Col1" />
</ListID>
</xsl:template>
<xsl:template match="row" mode="Col1">
<MainArt>
<ItemCode>
<xsl:value-of select="Col1"/>
</ItemCode>
<List>
<xsl:apply-templates select="key('Col1', concat(Col6, '|', Col1))[generate-id() = generate-id(key('Col9', concat(Col6, '|', Col1, '|', Col9))[1])]" mode="Col9" />
</List>
</MainArt>
</xsl:template>
<xsl:template match="row" mode="Col9">
<SubArt>
<ItemCode>
<xsl:value-of select="Col9"/>
</ItemCode>
<SubArtList>
<xsl:apply-templates select="key('Col9', concat(Col6, '|', Col1, '|', Col9))" mode="Col12" />
</SubArtList>
</SubArt>
</xsl:template>
<xsl:template match="row" mode="Col12">
<row>
<ItemCode>
<xsl:value-of select="Col12"/>
</ItemCode>
<Quantity>
<xsl:value-of select="Col14"/>
</Quantity>
</row>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<Doc>
<ListID id="01">
<MainArt>
<ItemCode>13820PKS-</ItemCode>
<List>
<SubArt>
<ItemCode>1507462800</ItemCode>
<SubArtList>
<row>
<ItemCode>15074628</ItemCode>
<Quantity>4</Quantity>
</row>
<row>
<ItemCode>15074629</ItemCode>
<Quantity>5</Quantity>
</row>
</SubArtList>
</SubArt>
<SubArt>
<ItemCode>1808502801</ItemCode>
<SubArtList>
<row>
<ItemCode>18085021</ItemCode>
<Quantity>1</Quantity>
</row>
</SubArtList>
</SubArt>
</List>
</MainArt>
</ListID>
<ListID id="02">
<MainArt>
<ItemCode>13820PKS-</ItemCode>
<List>
<SubArt>
<ItemCode>2710004100</ItemCode>
<SubArtList>
<row>
<ItemCode>2710004100</ItemCode>
<Quantity>1</Quantity>
</row>
</SubArtList>
</SubArt>
</List>
</MainArt>
</ListID>
</Doc>