XSLT:将Xpath属性与for-each范围的属性相匹配

时间:2010-01-12 14:33:16

标签: xslt scope foreach

我想我的问题很常见,所以必须有一个简单的解决方案。请考虑以下xml片段:

  <categories>
    <category name="cat1" />
    <category name="cat2" />
    <category name="cat3" />
    <category name="cat4" />
  </categories>
  <data>
    <catval name="cat2">foo</catval>
    <catval name="cat4">bar</catval>
    <catval name="cat3">boo</catval>
  </data>

我需要按照categories元素中定义的顺序输出catval值(包括没有数据的类别)。请注意,在实际输入xml中,整个地方都有多个数据元素,输出更复杂,因此为类别创建模板是不可行的。我正在使用如下构造:

<xsl:template match="data">
    <xsl:variable name="currentdata" select="." />
    <xsl:for-each select="../categories/category">
      <xsl:value-of select="@name" />: 
      <xsl:value-of 
        select="$currentdata/catval[@name=@name]" /> <!-- ??? -->
    </xsl:for-each>
</xsl:template>

我不知道这是否是解决我问题的最佳方法,但即使不是:我怎样才能将$ currentdata / catval的 name 属性与 for-each循环上下文中 category 元素的名称属性?

3 个答案:

答案 0 :(得分:3)

简单,优雅,高效:

<xsl:key name="catvalByName" match="catval" use="@name" />

<xsl:template match="category">
  <xsl:value-of select="@name" />
  <xsl:text>: </xsl:text>
  <xsl:value-of select="key('catvalByName', @name)" />
  <xsl:text>&#10;</xsl:text>
</xsl:template>

输出:

cat1: 
cat2: foo
cat3: boo
cat4: bar

这样调用时,例如:

<xsl:template match="categories">
  <xsl:apply-templates select="category" />
</xsl:template>

答案 1 :(得分:1)

使用变量保存<xsl:for-each>范围内的属性值:

<xsl:template match="data">
  <xsl:variable name="currentdata" select="." />
  <xsl:for-each select="../categories/category">
    <xsl:variable name="name" select="@name"/>
    <xsl:value-of select="$name" />: 
    <xsl:value-of 
      select="$currentdata/catval[@name=$name]" /> <!-- ??? -->
  </xsl:for-each>
</xsl:template>

答案 2 :(得分:0)

我会走另一条路:

<xsl:template match="categories">
   <xsl:for-each select="category">
     <xsl:variable name="name" select="@name"/>
     <xsl:apply-template select="/data/catval[@name=$name]/>
   </xsl:for-each>
</xsl:template>

<xsl:template match="catval">
  <!-- Your output logic here -->
</xsl:template>

所以,一旦你进入“catval”模板,你就确定订单已经完成,你只需要关注输出格式。