在XSLT中为每个组正确使用
我有以下xml示例:在XSLT中为每个组正确使用,xslt,Xslt,我有以下xml示例: <items> <item> <item_id>1</item_id> <item_name>item 1</item_name> <group_id>1</group_id> <group_name>group 1</group_name> </item>
<items>
<item>
<item_id>1</item_id>
<item_name>item 1</item_name>
<group_id>1</group_id>
<group_name>group 1</group_name>
</item>
<item>
<item_id>2</item_id>
<item_name>item 2</item_name>
<group_id>1</group_id>
<group_name>group 1</group_name>
</item>
<item>
<item_id>3</item_id>
<item_name>item 3</item_name>
<group_id>2</group_id>
<group_name>group 2</group_name>
</item>
</items>
在xml中,item_id后面总是跟着item_name。项目名称不一定总是concat('item_u',#)。可以是“牙膏”之类的描述。项目将永远不会在文件中重复,但偶尔组\u id->组\u名称配对将不总是1-1。在这种情况下,最好进行第一次配对
我使用“每个小组”的语句来实现这一点,但它似乎有点粗糙。这种方法有什么缺点吗?有什么更好的方法可以做到这一点
,
hmmm。。这不是一个真正的缺点,但它在XSLT1.0中不起作用,因为它不支持每个组的
:-/
我认为您不需要XSLT1.0解决方案。。但我仍然在发布我的作品:)看看这个
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/items">
<xsl:call-template name="items_grouping">
<xsl:with-param name="list" select="'item'"/>
</xsl:call-template>
<xsl:call-template name="items_grouping">
<xsl:with-param name="list" select="'group'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="items_grouping">
<xsl:param name="list"/>
<xsl:variable name="linefeed" select="'
'"></xsl:variable>
<xsl:variable name="list_id" select="concat($list,'_id')"></xsl:variable>
<xsl:variable name="list_name" select="concat($list,'_name')"></xsl:variable>
<xsl:for-each select="item">
<xsl:for-each select="*[name()=$list_id and not(.= ../preceding-sibling::item/*[name()=$list_id]/.)]">
<xsl:value-of select="concat(.,',')"/>
<xsl:value-of select="../*[name()=$list_name]"/>
<xsl:value-of select="$linefeed"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
使用与你相同的方法。。唯一的变化是'previous-sibling'
对于这段代码,
的子节点顺序并不重要这里是一个简单而简短的XSLT 2.0(根据要求)解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates/>
<xsl:for-each-group select="/*/*/group_id" group-by=".">
<xsl:value-of separator="," select="../*[starts-with(name(), 'group_')]"/>
<xsl:text>
</xsl:text>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="item">
<xsl:value-of separator="," select="*[starts-with(name(), 'item_')]"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<items>
<item>
<item_id>1</item_id>
<item_name>item 1</item_name>
<group_id>1</group_id>
<group_name>group 1</group_name>
</item>
<item>
<item_id>2</item_id>
<item_name>item 2</item_name>
<group_id>1</group_id>
<group_name>group 1</group_name>
</item>
<item>
<item_id>3</item_id>
<item_name>item 3</item_name>
<group_id>2</group_id>
<group_name>group 2</group_name>
</item>
</items>
1,item 1
2,item 2
3,item 3
1,group 1
2,group 2
是否保证1
后面始终紧跟着:item 1
(或者通常紧跟着item\u name
具有相同值的元素)?如果这是有保证的,那么您必须告诉我们,在许多可能的item\u name
值中选择与给定item\u id
元素balue一起显示的附加规则是什么。在这个文件中,item\u id后面总是跟item\u name。项目名称不一定总是concat('item_u',#)。可以是“牙膏”之类的描述。项目将永远不会在文件中重复,但偶尔组\u id->组\u名称配对将不总是1-1。在这种情况下,最好进行第一次配对。user1193339:您必须编辑问题并在那里提供此信息——否则它是不明确的,人们不希望通过猜测来解决。此外,您的数据也不太具有代表性,项
元素没有重复的ID和值,那么为什么要使用分组呢?我想我面临的主要问题是如何处理多个group\u id->group\u name对,并且只提取每个group\u id和与该id关联的名称的第一个匹配项。我并不特别需要分组功能,它似乎给了我想要的功能,尽管我认为有一种更正确的方法来实现去做吧。
<items>
<item>
<item_id>1</item_id>
<item_name>item 1</item_name>
<group_id>1</group_id>
<group_name>group 1</group_name>
</item>
<item>
<item_id>2</item_id>
<item_name>item 2</item_name>
<group_id>1</group_id>
<group_name>group 1</group_name>
</item>
<item>
<item_id>3</item_id>
<item_name>item 3</item_name>
<group_id>2</group_id>
<group_name>group 2</group_name>
</item>
</items>
1,item 1
2,item 2
3,item 3
1,group 1
2,group 2