使用xslt从xml中提取唯一组
我意识到不能在xsl中使用数组,通常要完成下面的任务需要一个数组。这是我需要的 示例xml代码使用xslt从xml中提取唯一组,xml,xslt,xslt-grouping,Xml,Xslt,Xslt Grouping,我意识到不能在xsl中使用数组,通常要完成下面的任务需要一个数组。这是我需要的 示例xml代码 <products> <product> <productNumber>1</productNumber> <productType>TypeA</productType> </product> <product> <productNumber>2</productNum
<products>
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</products>
而不是
TypeA
TypeB
TypeA
TypeC
TypeA
我不是唯一一个寻找这种功能的人
思想?这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kProdByType"
match="product" use="productType"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<products>
<xsl:apply-templates select=
"product[generate-id()
=
generate-id(key('kProdByType', productType)[1])
]
"/>
</products>
</xsl:template>
<xsl:template match="product">
<productType value="{productType}">
<xsl:apply-templates mode="copy"
select="key('kProdByType', productType)"/>
</productType>
</xsl:template>
<xsl:template match="product" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
<products>
<productType value="TypeA">
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</productType>
<productType value="TypeB">
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
</productType>
<productType value="TypeC">
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
</productType>
</products>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<xsl:for-each-group select="product"
group-by="productType">
<productType value="{productType}">
<xsl:apply-templates select="current-group()"/>
</productType>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<products>
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</products>
1.
A型
2.
B型
3.
A型
4.
C型
5.
A型
生成所需的正确分组:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kProdByType"
match="product" use="productType"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<products>
<xsl:apply-templates select=
"product[generate-id()
=
generate-id(key('kProdByType', productType)[1])
]
"/>
</products>
</xsl:template>
<xsl:template match="product">
<productType value="{productType}">
<xsl:apply-templates mode="copy"
select="key('kProdByType', productType)"/>
</productType>
</xsl:template>
<xsl:template match="product" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
<products>
<productType value="TypeA">
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</productType>
<productType value="TypeB">
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
</productType>
<productType value="TypeC">
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
</productType>
</products>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<xsl:for-each-group select="product"
group-by="productType">
<productType value="{productType}">
<xsl:apply-templates select="current-group()"/>
</productType>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
1.
A型
3.
A型
5.
A型
2.
B型
4.
C型
注意:这是著名的Muenchian分组方法的一个示例,它是XSLT 1.0中已知的最快的凿槽技术
XSLT 2.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kProdByType"
match="product" use="productType"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<products>
<xsl:apply-templates select=
"product[generate-id()
=
generate-id(key('kProdByType', productType)[1])
]
"/>
</products>
</xsl:template>
<xsl:template match="product">
<productType value="{productType}">
<xsl:apply-templates mode="copy"
select="key('kProdByType', productType)"/>
</productType>
</xsl:template>
<xsl:template match="product" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
<products>
<productType value="TypeA">
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</productType>
<productType value="TypeB">
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
</productType>
<productType value="TypeC">
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
</productType>
</products>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<xsl:for-each-group select="product"
group-by="productType">
<productType value="{productType}">
<xsl:apply-templates select="current-group()"/>
</productType>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
当对提供的XML文档应用此XSLT 2.0转换时,将生成完全相同的、正确分组的结果此转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kProdByType"
match="product" use="productType"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<products>
<xsl:apply-templates select=
"product[generate-id()
=
generate-id(key('kProdByType', productType)[1])
]
"/>
</products>
</xsl:template>
<xsl:template match="product">
<productType value="{productType}">
<xsl:apply-templates mode="copy"
select="key('kProdByType', productType)"/>
</productType>
</xsl:template>
<xsl:template match="product" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
<products>
<productType value="TypeA">
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</productType>
<productType value="TypeB">
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
</productType>
<productType value="TypeC">
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
</productType>
</products>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<xsl:for-each-group select="product"
group-by="productType">
<productType value="{productType}">
<xsl:apply-templates select="current-group()"/>
</productType>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<products>
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</products>
1.
A型
2.
B型
3.
A型
4.
C型
5.
A型
生成所需的正确分组:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kProdByType"
match="product" use="productType"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<products>
<xsl:apply-templates select=
"product[generate-id()
=
generate-id(key('kProdByType', productType)[1])
]
"/>
</products>
</xsl:template>
<xsl:template match="product">
<productType value="{productType}">
<xsl:apply-templates mode="copy"
select="key('kProdByType', productType)"/>
</productType>
</xsl:template>
<xsl:template match="product" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
<products>
<productType value="TypeA">
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</productType>
<productType value="TypeB">
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
</productType>
<productType value="TypeC">
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
</productType>
</products>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<xsl:for-each-group select="product"
group-by="productType">
<productType value="{productType}">
<xsl:apply-templates select="current-group()"/>
</productType>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
1.
A型
3.
A型
5.
A型
2.
B型
4.
C型
注意:这是著名的Muenchian分组方法的一个示例,它是XSLT 1.0中已知的最快的凿槽技术
XSLT 2.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kProdByType"
match="product" use="productType"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<products>
<xsl:apply-templates select=
"product[generate-id()
=
generate-id(key('kProdByType', productType)[1])
]
"/>
</products>
</xsl:template>
<xsl:template match="product">
<productType value="{productType}">
<xsl:apply-templates mode="copy"
select="key('kProdByType', productType)"/>
</productType>
</xsl:template>
<xsl:template match="product" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
<products>
<productType value="TypeA">
<product>
<productNumber>1</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>3</productNumber>
<productType>TypeA</productType>
</product>
<product>
<productNumber>5</productNumber>
<productType>TypeA</productType>
</product>
</productType>
<productType value="TypeB">
<product>
<productNumber>2</productNumber>
<productType>TypeB</productType>
</product>
</productType>
<productType value="TypeC">
<product>
<productNumber>4</productNumber>
<productType>TypeC</productType>
</product>
</productType>
</products>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/products">
<xsl:for-each-group select="product"
group-by="productType">
<productType value="{productType}">
<xsl:apply-templates select="current-group()"/>
</productType>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
当对提供的XML文档应用XSLT 2.0转换时,会产生完全相同的、正确分组的结果Dimitre让我走上了正确的道路。下面是我根据自己的需要编写的代码,一个支持AJAX调用的简单的无限制输出流
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8"/>
<xsl:key name="kProdByBrand" match="Products/Product" use="Brand"/>
<xsl:template match="Products">
<xsl:for-each
select="Product
[generate-id() = generate-id(key('kProdByBrand', Brand)[1])]"><xsl:sort
select="Brand" /><xsl:value-of select="Brand" />|</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
迪米特里让我走上了正确的道路。下面是我根据自己的需要编写的代码,一个支持AJAX调用的简单的无限制输出流
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8"/>
<xsl:key name="kProdByBrand" match="Products/Product" use="Brand"/>
<xsl:template match="Products">
<xsl:for-each
select="Product
[generate-id() = generate-id(key('kProdByBrand', Brand)[1])]"><xsl:sort
select="Brand" /><xsl:value-of select="Brand" />|</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
好问题(+1)。请参阅我的答案,了解有效的分组XSLT 1.0解决方案。:)好问题(+1)。请参阅我的答案,了解有效的分组XSLT 1.0解决方案。:)六羟甲基三聚氰胺六甲醚。。。谢谢你!我将把它注入到我的代码中,看看它是如何工作的,并让您知道。这很酷,因为它为我打开了更多的可能性。@Jimmmy:我很高兴你发现我的答案很有用。表达这一点的方式是接受答案(通过单击答案旁边的复选标记图片)。:)@Dimitre:+1表示XSLT1.0和XSLT2.0解决方案。另外,添加标记
xslt分组
Thank guys。我想看看这个解决方案在我的实际案例中是如何对我起作用的。我可能还有更多的问题,这就是为什么我还没有将其标记为已回答:)还有更多问题要问@吉米:进一步的问题将是新的,单独的问题。你和我们已经解决了这个问题。嗯。。。谢谢你!我将把它注入到我的代码中,看看它是如何工作的,并让您知道。这很酷,因为它为我打开了更多的可能性。@Jimmmy:我很高兴你发现我的答案很有用。表达这一点的方式是接受答案(通过单击答案旁边的复选标记图片)。:)@Dimitre:+1表示XSLT1.0和XSLT2.0解决方案。另外,添加标记xslt分组
Thank guys。我想看看这个解决方案在我的实际案例中是如何对我起作用的。我可能还有更多的问题,这就是为什么我还没有将其标记为已回答:)还有更多问题要问@吉米:进一步的问题将是新的,单独的问题。你和我们已经解决了这个问题。