使用xslt和子节点分组
我在这里尝试了一些示例,但仍然无法获得正确的输出。我以前很少使用XSLT。我想对“Detail”元素进行分组,并将所有与该组匹配的“Data”元素作为“Detail”元素的子元素 例如: 输入使用xslt和子节点分组,xslt,grouping,Xslt,Grouping,我在这里尝试了一些示例,但仍然无法获得正确的输出。我以前很少使用XSLT。我想对“Detail”元素进行分组,并将所有与该组匹配的“Data”元素作为“Detail”元素的子元素 例如: 输入 1. 2. 3. 4. 5. 6. 想要的输出(“Detail type=“A”group=“1”>组合在一起的元素以及与该组匹配的所有元素作为子元素) 1. 2. 6. 3. 4. 5. 谢谢你的帮助:)注意:这个问题在我开始回答之前在垃圾箱里拖了6个小时。我的答案在垃圾箱里拖了两个小时,然后其
1.
2.
3.
4.
5.
6.
想要的输出(“Detail type=“A”group=“1”>组合在一起的元素以及与该组匹配的所有元素作为子元素)
1.
2.
6.
3.
4.
5.
谢谢你的帮助:)注意:这个问题在我开始回答之前在垃圾箱里拖了6个小时。我的答案在垃圾箱里拖了两个小时,然后其他人把一些不重要的评论伪装成了答案
研究明钦族的分组问题。这对解决这些分组问题很方便 重型升降机是
,它基于@type和@group的concat创建一个键,这里的这一行是
,它隔离具有特定键的详图节点的第一次出现,并通过扩展@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>
注意:这个问题在我回答之前在垃圾箱里拖了6个小时。我的答案在垃圾箱里拖了两个小时,然后其他人把一些不重要的评论伪装成了答案
研究明钦族的分组问题。这对解决这些分组问题很方便 重型升降机是
,它基于@type和@group的concat创建一个键,这里的这一行是
,它隔离具有特定键的详图节点的第一次出现,并通过扩展@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>
I.XSLT 1.0 这里有一个解决方案,它使用面向推送的模板,而不是
(这通常是一种更可重用的方法)
当此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 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>
<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,将产生相同的正确结果。
说明:
<?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 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>
<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>
- 通过正确应用XSLT2.0的元素,我们可以得到相同的结果
(这通常是一种更可重用的方法)
当此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 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>
<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,将产生相同的正确结果。
说明:
<?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 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>
<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>
- 通过正确应用XSLT2.0的元素,我们可以得到相同的结果