代码之家  ›  专栏  ›  技术社区  ›  FRotthowe

xslt:将xpath属性与每个作用域的属性进行匹配

  •  1
  • FRotthowe  · 技术社区  · 15 年前

    我想我的问题很常见,所以必须有一个简单的解决办法。请考虑以下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的属性 名称 的属性 类别 元素在for each循环的上下文中?

    3 回复  |  直到 15 年前
        1
  •  1
  •   Roland Bouman    15 年前

    使用变量保存 <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
  •  3
  •   Tomalak    15 年前

    简单、优雅、高效:

    <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>
    
        3
  •  0
  •   gizmo    15 年前

    我会走另一条路:

    <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”模板,您就可以确定已经完成了排序,并且只需关注输出格式。