请指导我使用xslt1.0进行基于属性值的muenchian分组



我想使用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(&apos;camp&apos;,field)[1])]">
<Campaigns>
<campaignNumber>
<xsl:value-of select="item/field[@name=&apos;CAMPAIGNCODE&apos;]" />
</campaignNumber>
<xsl:for-each xmltem="http://tempuri.org" select="key(&apos;camp&apos;,field)">
<downPayment>
<xsl:value-of select="item/field[@name=&apos;DOWNPAYMENT&apos;]" />
</downPayment>
<ballonPayment>
<xsl:value-of select="item/field[@name=&apos;BALLOONPAYMENT&apos;]" />
</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()现在将按照排序的顺序为您提供位置,而您需要原始文档顺序中的位置。

最新更新