<ROOT>
<AA Aattr="xyz1">
<BB bAttr1="firefox" bAttr2="aaa" >
</BB>
<BB bAttr1="chrome" bAttr2="aaa" >
</BB>
<BB bAttr1="firefox" bAttr2="bbb" >
</BB>
<BB bAttr1="chrome" bAttr2="bbb" >
</BB>
</AA>
<AA Aattr="xyz2">
<BB bAttr1="firefox" bAttr2="aaa" >
</BB>
<BB bAttr1="chrome" bAttr2="ccc" >
</BB>
<BB bAttr1="firefox" bAttr2="ddd" >
</BB>
</AA>
我想在节点'BB'中从节点'AA'中选择attibute'bAttr2'的不同\唯一值,其中属性'Aattr'是xyz1
对于给定的xml,我需要输出为“aaa”,“bbb”
我使用密钥尝试了以下逻辑。但没有奏效。请帮忙
<xsl:key name="nameDistinct" match="BB" use="@bAttr1"/>
<xsl:template match="/">
<xsl:for-each select="ROOT/AA[@Aattr='xyz1']">
<xsl:for-each select="BB[generate-id()=generate-id(key('nameDistinct',@bAttr2)[1])]">
<xsl:value-of select="@bAttr2"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
答案 0 :(得分:3)
这里有两个选项:
在定义键时过滤键的可用项:
<xsl:key name="nameDistinct" match="AA[@Aattr = 'xyz1']/BB" use="@bAttr2"/>
<xsl:template match="/">
<xsl:for-each
select="ROOT/AA/BB[generate-id() =
generate-id(key('nameDistinct', @bAttr2)[1])]">
<xsl:value-of select="@bAttr2"/>
</xsl:for-each>
</xsl:template>
或在分组表达式中过滤:
<xsl:key name="nameDistinct" match="BB" use="@bAttr2"/>
<xsl:template match="/">
<xsl:for-each
select="ROOT/AA/BB[generate-id() =
generate-id(key('nameDistinct', @bAttr2)
[../@Aattr = 'xyz1']
[1])]">
<xsl:value-of select="@bAttr2"/>
</xsl:for-each>
</xsl:template>
前一种方法稍微麻烦一点,效率稍高,而后一种方法允许您参数化分组(即非硬编码为'xyz1'的值组),例如:
<xsl:key name="nameDistinct" match="BB" use="@bAttr2"/>
<xsl:template match="/">
<xsl:for-each select="ROOT/AA">
<xsl:for-each
select="BB[generate-id() =
generate-id(key('nameDistinct', @bAttr2)
[../@Aattr = current()/@Aattr]
[1])]">
<xsl:value-of select="@bAttr2"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
答案 1 :(得分:2)
此转化:
<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="kCompoundAttribs" match="BB"
use="concat(generate-id(..), '+', @bAttr2)"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/*[1]/*
[generate-id()
=
generate-id(key('kCompoundAttribs',
concat(generate-id(..),'+', @bAttr2)
)[1]
)
]"/>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<ROOT>
<AA Aattr="xyz1">
<BB bAttr1="firefox" bAttr2="aaa" ></BB>
<BB bAttr1="chrome" bAttr2="aaa" ></BB>
<BB bAttr1="firefox" bAttr2="bbb" ></BB>
<BB bAttr1="chrome" bAttr2="bbb" ></BB>
</AA>
<AA Aattr="xyz2">
<BB bAttr1="firefox" bAttr2="aaa" ></BB>
<BB bAttr1="chrome" bAttr2="ccc" ></BB>
<BB bAttr1="firefox" bAttr2="ddd" ></BB>
</AA>
</ROOT>
生成两个BB
元素,其bAttr2
属性具有所需的一组不同值(如果您只想要属性的字符串值,只需使用{{1 }或xsl:apply-templates
表达式):
xsl:for-each
请注意:
此解决方案比“过滤”更简单,更容易理解和更有效:)