我想使用muenchian分组对元素进行分组。我用的是xslt 1.0,你能给我指引一下吗?
xml如下所示。。
<responseDA xmlns:tem="http://tempuri.org">
<outputData>
<dictionary id="AutoOutputs">
<list numOfItems="2">
<item>
<field dataType="double" name="DOWNPAYMENT">2000.00</field>
</item>
<item>
<field dataType="double" name="DOWNPAYMENT">3000.00</field>
</item>
</list>
<list numOfItems="2">
<item>
<field dataType="string" name="CAMPAIGNCODE">A</field>
</item>
<item>
<field dataType="string" name="CAMPAIGNCODE">B</field>
</item>
</list>
<list numOfItems="2">
<item>
<field dataType="double" name="BALLOONPAYMENT">4000.00</field>
</item>
<item>
<field dataType="double" name="BALLOONPAYMENT">5000.00</field>
</item>
</list>
</dictionary>
</outputData>
</responseDA>
现在我需要根据列表属性中的"numofitems"对活动进行分组。输出应为.
<Campaigns>
<campaignNumber>A</ns:campaignNumber>
<downPayment>2000.00</ns:downPayment>
<ballonPayment>4000.00</ns:ballonPayment>
</Campaigns>
<Campaigns>
<campaignNumber>B</ns:campaignNumber>
<downPayment>3000.00</ns:downPayment>
<ballonPayment>5000.00</ns:ballonPayment>
</Campaigns>
我试过了,但没用。。。
<xsl:template match="/">
<xsl:apply-templates select="responseDA" />
</xsl:template>
<xsl:key name="camp" match="//list/@numOfItems" use="field" />
<xsl:template match="responseDA">
<xsl:for-each select="list/@numOfItems[generate-id(.)=generate-id(key('camp',field)[1])]">
<Campaigns>
<campaignNumber>
<xsl:value-of select="item/field[@name='CAMPAIGNCODE']" />
</campaignNumber>
<xsl:for-each xmltem="http://tempuri.org" select="key('camp',field)">
<downPayment>
<xsl:value-of select="item/field[@name='DOWNPAYMENT']" />
</downPayment>
<ballonPayment>
<xsl:value-of select="item/field[@name='BALLOONPAYMENT']" />
</ballonPayment>
</xsl:for-each>
</Campaigns>
</xsl:for-each>
</xsl:template>
请纠正我哪里做错了。。。
问候,Inian
在我看来,这不像是一个需要Muenchian分组的问题。您只需为列表中(任意一个)的每个item
创建一个输出"行",其值取自其他列表中相应的位置:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<root>
<xsl:apply-templates select="//list[1]/item"/>
</root>
</xsl:template>
<xsl:template match="item">
<xsl:variable name="mypos" select="position()"/>
<xsl:variable name="fields" select="//list/item[$mypos]/field"/>
<Campaigns>
<campaignNumber>
<xsl:value-of select="$fields[@name='CAMPAIGNCODE']"/>
</campaignNumber>
<downPayment>
<xsl:value-of select="$fields[@name='DOWNPAYMENT']"/>
</downPayment>
<ballonPayment>
<xsl:value-of select="$fields[@name='BALLOONPAYMENT']"/>
</ballonPayment>
</Campaigns>
</xsl:template>
</xsl:stylesheet>
当在示例输入XML上运行时,它会产生您请求的输出:
<?xml version="1.0"?>
<root>
<Campaigns>
<campaignNumber>A</campaignNumber>
<downPayment>2000.00</downPayment>
<ballonPayment>4000.00</ballonPayment>
</Campaigns>
<Campaigns>
<campaignNumber>B</campaignNumber>
<downPayment>3000.00</downPayment>
<ballonPayment>5000.00</ballonPayment>
</Campaigns>
</root>
(封装在单个根级元素中,使其成为格式良好的XML)。
你在评论中说你需要"对活动进行排序"-你可以在apply-templates
的位置进行排序,记住我上面给出的模板规则并不关心它正在处理哪个行的项目,只关心它处理同一行的所有项目。
<xsl:template match="/">
<root>
<xsl:apply-templates select="//list[item/field/@name = 'CAMPAIGNCODE']/item">
<xsl:sort select="field" />
</xsl:apply-templates>
</root>
</xsl:template>
但是您还需要更改mypos
变量的定义:
<xsl:template match="item">
<xsl:variable name="mypos" select="count(preceding-sibling::item) + 1"/>
因为position()
现在将按照排序的顺序为您提供位置,而您需要原始文档顺序中的位置。