我希望能够从具有特定子元素的重复组(使用Muenchian分组完成)中选择一个元素。我的XML看起来像这样:
<waybill>
<shipment>
<parcel>
<sscc>SSCC1</sscc>
<consignee>Receiver1</consignee>
<date>Date1</date>
<status>Status1</status>
</parcel>
<parcel>
<sscc>SSCC2</sscc>
<consignee>Receiver2</consignee>
<attention>Note2</attention>
</parcel>
<parcel>
<sscc>SSCC3</sscc>
<consignee>Receiver3</consignee>
</parcel>
<parcel>
<sscc>SSCC4</sscc>
<consignee>Receiver4</consignee>
</parcel>
<parcel>
<sscc>SSCC1</sscc>
<consignee>Receiver1</consignee>
<attention>Note1</attention>
<date>Date2</date>
<status>Status2</status>
</parcel>
<parcel>
<sscc>SSCC3</sscc>
<consignee>Receiver3</consignee>
<attention>Note3</attention>
</parcel>
</shipment>
</waybill>
我的XSLT看起来像这样:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" version="2.0">
<xsl:output method="text" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:key name="ean" match="parcel" use="sscc"/>
<xsl:template match="/">
<xsl:for-each select="/waybill/shipment/parcel[generate-id()=generate-id(key('ean',sscc))]">
<xsl:value-of select="current()/sscc"/>
<xsl:text>§</xsl:text>
<xsl:value-of select="current()/consignee"/>
<xsl:text>§</xsl:text>
<xsl:value-of select="current()/attention"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出现在看起来像这样:
SSCC1§Receiver1§
SSCC2§Receiver2§Note2
SSCC3§Receiver3§
SSCC4§Receiver4§
所以我的XSLT现在将从分组元素中选择第一个匹配,并且我希望得到的结果是:
SSCC1§Receiver1§Note1
SSCC2§Receiver2§Note2
SSCC3§Receiver3§Note3
SSCC4§Receiver4§
因此,XSLT应该从具有最多数据的组中找到那些重复项。不是第一个或最后一个,而是具有某个子元素的那个(或者在我的最后一个案例中:子子元素)
在这种情况下,并非所有元素都具有子元素(此处为SSCC4),并且这些元素应与其拥有的数据一起使用(不应忽略)。
从分组的相似元素中找到“最佳”元素的正确方法是什么?
非常感谢任何帮助:)
答案 0 :(得分:2)
您可以从key()
导航,如下所示:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" version="2.0">
<xsl:output method="text" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:key name="ean" match="parcel" use="sscc"/>
<xsl:template match="/">
<xsl:for-each select="/waybill/shipment/parcel[generate-id()=generate-id(key('ean',sscc))]">
<xsl:variable name="group" select="key('ean',sscc)" />
<xsl:value-of select="sscc"/>
<xsl:text>§</xsl:text>
<xsl:value-of select="$group/consignee"/>
<xsl:text>§</xsl:text>
<xsl:value-of select="$group/attention"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
key('ean',sscc)
会选择当前论坛的所有<parcel>
元素,并选择key('ean',sscc)/attention
所有<attention>
元素。
在XSLT 2.0+中,您还可以使用<xsl:for-each-group>
和current-group()
函数获得相同的效果。
在key('ean',sscc)/attention
中使用<xsl:value-of>
只能打印第一场比赛的值,无论如何,这都是您的意图。
像你一样明确地使用current()
并不是必需的。 current()
意味着在XPath谓词中使用,在正常的select
表达式中,它不会添加任何值。