我在这里尝试了一些例子,但我仍然无法获得正确的输出。我之前没有使用过XSLT。我想分组"详细信息"元素并得到所有"数据"将该组作为子项匹配到"详细信息"元件。
示例:
输入
<?xml version="1.0" encoding="utf-8"?>
<File>
<Detail type="A" group="1" >
<Data>
<Nr>1</Nr>
</Data>
<Data>
<Nr>2</Nr>
</Data>
</Detail>
<Detail type="B" group="1">
<Data>
<Nr>3</Nr>
</Data>
<Data>
<Nr>4</Nr>
</Data>
</Detail>
<Detail type="B" group="2">
<Data>
<Nr>5</Nr>
</Data>
</Detail>
<Detail type="A" group="1">
<Data>
<Nr>6</Nr>
</Data>
</Detail>
</File>
通缉输出(&#34;详细信息类型=&#34; A&#34;组=&#34; 1&#34;&gt;组合在一起的元素以及与该组匹配的所有元素作为子项)
<?xml version="1.0" encoding="utf-8"?>
<File>
<Detail type="A" group="1" >
<Data>
<Nr>1</Nr>
</Data>
<Data>
<Nr>2</Nr>
</Data>
<Data>
<Nr>6</Nr>
</Data>
</Detail>
<Detail type="B" group="1">
<Data>
<Nr>3</Nr>
</Data>
<Data>
<Nr>4</Nr>
</Data>
</Detail>
<Detail type="B" group="2">
<Data>
<Nr>5</Nr>
</Data>
</Detail>
</File>
感谢您的帮助:)
答案 0 :(得分:3)
<强>予。 XSLT 1.0
这是一个使用面向推送模板的解决方案,而不是<xsl:for-each>
(通常是一种更可重用的方法)。
当这个XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="kDetailAttr" match="Detail" use="concat(@type, '+', @group)" />
<xsl:template match="/*">
<File>
<xsl:apply-templates select="Detail[generate-id() = generate-id(key('kDetailAttr', concat(@type, '+', @group))[1])]" />
</File>
</xsl:template>
<xsl:template match="Detail">
<Detail type="{@type}" group="{@group}">
<xsl:copy-of select="key('kDetailAttr', concat(@type, '+', @group))/Data" />
</Detail>
</xsl:template>
</xsl:stylesheet>
...适用于原始XML:
<?xml version="1.0" encoding="UTF-8"?>
<File>
<Detail type="A" group="1">
<Data>
<Nr>1</Nr>
</Data>
<Data>
<Nr>2</Nr>
</Data>
</Detail>
<Detail type="B" group="1">
<Data>
<Nr>3</Nr>
</Data>
<Data>
<Nr>4</Nr>
</Data>
</Detail>
<Detail type="B" group="2">
<Data>
<Nr>5</Nr>
</Data>
</Detail>
<Detail type="A" group="1">
<Data>
<Nr>6</Nr>
</Data>
</Detail>
</File>
...生成了想要的结果:
<?xml version="1.0" encoding="utf-8"?>
<File>
<Detail type="A" group="1">
<Data>
<Nr>1</Nr>
</Data>
<Data>
<Nr>2</Nr>
</Data>
<Data>
<Nr>6</Nr>
</Data>
</Detail>
<Detail type="B" group="1">
<Data>
<Nr>3</Nr>
</Data>
<Data>
<Nr>4</Nr>
</Data>
</Detail>
<Detail type="B" group="2">
<Data>
<Nr>5</Nr>
</Data>
</Detail>
</File>
<强>解释强>
Muenchian Grouping Method
(在XSLT 1.0中是必需的,因为它没有任何“内联”分组机制),我们可以找到唯一的节点并对它们的后代进行分组。<强> II。 XSLT 2.0
当这个XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<File>
<xsl:for-each-group select="Detail"
group-by="concat(@type, '+', @group)">
<Detail type="{@type}" group="{@group}">
<xsl:copy-of select="current-group()/Data" />
</Detail>
</xsl:for-each-group>
</File>
</xsl:template>
</xsl:stylesheet>
...应用于原始XML,生成相同的正确结果。
<强>解释强>
for-each-group
元素,我们可以得到相同的结果。答案 1 :(得分:1)
注意:在我拿起它之前,这个问题已经在垃圾箱中淹没了6个小时。我的答案在垃圾桶里徘徊了两个小时,然后其他人伪装了一些非必要的评论作为答案。
研究Muenchian分组。这对于这些分组问题很方便。
重型举重器是<xsl:key>
,它根据@type和@group的连续创建一个键,这一行<xsl:for-each select="File/Detail[count(. | key('details', concat(@type,'_',@group))[1]) = 1]">
隔离了第一次出现的详细节点特定的密钥和扩展特定的@group和@type配对。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="details" match="Detail"
use="concat(@type,'_',@group)"/>
<xsl:template match='/'>
<File>
<xsl:for-each select="File/Detail[count(. | key('details', concat(@type,'_',@group))[1]) = 1]">
<xsl:sort select="concat(@type,'_',@group)" />
<Detail type="{@type}" group="{@group}">
<xsl:for-each select="key('details', concat(@type,'_',@group))">
<xsl:copy-of select="Data"/>
</xsl:for-each>
</Detail>
</xsl:for-each>
</File>
</xsl:template>
</xsl:stylesheet>