我有一些像这样的
的XML<Data>
<MainItem>
<ItemGroup>Foo</ItemGroup>
<ItemDetails>Details</ItemDetails>
</MainItem>
<MainItem>
<ItemGroup>Bar</ItemGroup>
<ItemDetails>Details</ItemDetails>
</MainItem>
<MainItem>
<ItemGroup>Baz</ItemGroup>
<ItemDetails>Details</ItemDetails>
</MainItem>
<OtherData>
<ItemGroup>Foo</ItemGroup>
<OtherDataDetails>Blah</OtherDataDetails>
</OtherData>
<OtherData>
<ItemGroup>Bar</ItemGroup>
<OtherDataDetails>BlahBlah</OtherDataDetails>
</OtherData>
<OtherData>
<ItemGroup>Baz</ItemGroup>
<OtherDataDetails>BlahBlahBlahBlahBlah</OtherDataDetails>
</OtherData>
</Data>
我正在尝试转换的内容与此类似:
Foo
- Details
- Blah
Bar
- Details
- BlahBlah
Baz
- Details
- BlahBlahBlahBlahBlah
使用XSLT 1.0。
我正在通过做类似于Muenchian method的事情来完成分组;但我不确定如何将标签中的数据导入我的分组。有什么提示吗?
答案 0 :(得分:2)
尝试这样的事情:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:key name="groups" match="//ItemGroup" use="text()" />
<xsl:template match="/">
<Data>
<xsl:apply-templates
select="//ItemGroup[count( . | key('groups', text())[1]) = 1]" />
</Data>
</xsl:template>
<xsl:template match="ItemGroup">
<xsl:variable name="text" select="text()" />
<Group><xsl:value-of select="$text" /></Group>
<xsl:for-each select="/Data/*[ItemGroup = $text]/*[contains(name(), 'Details')]">
<Detail>- <xsl:value-of select="." /></Detail>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我为你设置了working example。
答案 1 :(得分:2)
以下分组解决方案不使用循环并处理ItemGroup
之后的任何其他同级元素。此外,只使用基于MainItem
的小键来识别组。
XSLT 1.0
制作文字:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="main" match="MainItem/ItemGroup" use="text()"/>
<xsl:template match="/Data">
<xsl:apply-templates select="MainItem"/>
</xsl:template>
<xsl:template match="MainItem">
<xsl:value-of select="ItemGroup"/><xsl:text>
</xsl:text>
<xsl:apply-templates select="ItemGroup[generate-id(.)=generate-id(key('main', current()/ItemGroup)[1])]"/>
</xsl:template>
<xsl:template match="ItemGroup">
<xsl:apply-templates select="/Data/*[ItemGroup = current()]/*/following-sibling::*"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:text>- </xsl:text><xsl:value-of select="."/><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
应用于您的输入,生成:
Foo
- Details
- Blah
Bar
- Details
- BlahBlah
Baz
- Details
- BlahBlahBlahBlahBlah
生成XML输出:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="main" match="MainItem/ItemGroup" use="text()"/>
<xsl:template match="/Data">
<xsl:copy>
<xsl:apply-templates select="MainItem"/>
</xsl:copy>
</xsl:template>
<xsl:template match="MainItem">
<xsl:variable name="id" select="ItemGroup"/>
<Group id="{$id}">
<xsl:apply-templates select="ItemGroup[generate-id(.)=generate-id(key('main', current()/ItemGroup)[1])]"/>
</Group>
</xsl:template>
<xsl:template match="ItemGroup">
<xsl:copy-of select="/Data/*[ItemGroup = current()]/*/following-sibling::*"/>
</xsl:template>
</xsl:stylesheet>
产生
<Data>
<Group id="Foo">
<ItemDetails>Details</ItemDetails>
<OtherDataDetails>Blah</OtherDataDetails>
</Group>
<Group id="Bar">
<ItemDetails>Details</ItemDetails>
<OtherDataDetails>BlahBlah</OtherDataDetails>
</Group>
<Group id="Baz">
<ItemDetails>Details</ItemDetails>
<OtherDataDetails>BlahBlahBlahBlahBlah</OtherDataDetails>
</Group>
</Data>
答案 2 :(得分:1)
这是一个非常简短且效率最高的转换,仅使用模板和密钥:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kGroupByVal" match="ItemGroup"
use="."/>
<xsl:key name="kNonGroupByGroup"
match="*[not(self::ItemGroup)]" use="../ItemGroup"/>
<xsl:template match=
"ItemGroup[generate-id()
=
generate-id(key('kGroupByVal',.)[1])
]
">
<xsl:value-of select="concat('
',.)"/>
<xsl:apply-templates mode="listGroup"
select="key('kNonGroupByGroup',.)"/>
</xsl:template>
<xsl:template match="*" mode="listGroup">
<xsl:value-of select="concat('
 - ', .)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于提供的XML文档:
<Data>
<MainItem>
<ItemGroup>Foo</ItemGroup>
<ItemDetails>Details</ItemDetails>
</MainItem>
<MainItem>
<ItemGroup>Bar</ItemGroup>
<ItemDetails>Details</ItemDetails>
</MainItem>
<MainItem>
<ItemGroup>Baz</ItemGroup>
<ItemDetails>Details</ItemDetails>
</MainItem>
<OtherData>
<ItemGroup>Foo</ItemGroup>
<OtherDataDetails>Blah</OtherDataDetails>
</OtherData>
<OtherData>
<ItemGroup>Bar</ItemGroup>
<OtherDataDetails>BlahBlah</OtherDataDetails>
</OtherData>
<OtherData>
<ItemGroup>Baz</ItemGroup>
<OtherDataDetails>BlahBlahBlahBlahBlah</OtherDataDetails>
</OtherData>
</Data>
产生了想要的正确结果:
Foo
- Details
- Blah
Bar
- Details
- BlahBlah
Baz
- Details
- BlahBlahBlahBlahBlah
**说明**:
Muenchian grouping获取ItemGroup
的不同值。
Key用于为ItemGroup
兄弟提供所有非ItemGroup
元素。
匹配任何文本节点的空模板,以防止built-in XSLT template 输出任何文本节点。