列出特定子元素的给定属性

时间:2009-01-04 17:18:31

标签: xml xslt

我有一些看起来像这样的XML代码

<SEARCHRESULTS>
  <FUNCTION name="BarGraph">
    <PARAMETER name="numList"></PARAMETER>
    <PARAMETER name="maxValue"></PARAMETER>
    <CODE>Some code</CODE>
  </FUNCTION>
</SEARCHRESULTS>

我想为每个函数提取一个参数名列表,到目前为止我已经得到了以下xsl代码

<xsl:for-each select="SEARCHRESULTS/FUNCTION">
  <ROW>
    <COL><DATA><xsl:value-of select="@name" /></DATA></COL>
    <COL><DATA><xsl:value-of select="PARAMETER/@name" /></DATA></COL>
    <COL><DATA><xsl:value-of select="CODE" /></DATA></COL>
  </ROW>
</xsl:for-each>

当然会返回第一个参数的名称以及函数名称和代码。

我想要一个文本字符串中函数的所有参数列表。返回分隔是最好的,但只要所有名称都在字符串中,我就可以在以后解析它。

我可以在目标数据库中规范化参数记录 - 但我不会这样做,我只需要它们用于显示目的,所以我不想付出太多精力。这就是为什么我是寻找一个简单的文本字符串。

我认为可能有某种方法只是将星号放入其中。如果不是,我将创建一个变量并添加另一个for-each来构建一个字符串 - 但它似乎应该有一个更简单的方法

生成的XML应该看起来像

<ROW>
  <COL><DATA>BarGraph</DATA></COL>
  <COL><DATA>numList;maxValue</DATA></COL>
  <COL><DATA>Some code</DATA></COL>
</ROW>

哪里';'在第二列中可以是回车符或我可以指定的另一个字符

4 个答案:

答案 0 :(得分:3)

尝试第二个foreach:

<xsl:template match="/">
<xsl:for-each select="SEARCHRESULTS/FUNCTION">
  <ROW>
    <COL>
      <DATA>
        <xsl:value-of select="@name" />
      </DATA>
    </COL>
    <COL>
      <DATA>
        <xsl:for-each select="PARAMETER">
          <!-- separate the names by a semicolon (do not insert a semicolon the first time -->
          <xsl:if test="position() > 1">
            <xsl:text>;</xsl:text>
          </xsl:if>
          <xsl:value-of select="@name" />
        </xsl:for-each>
      </DATA>
    </COL>
    <COL>
      <DATA>
        <xsl:value-of select="CODE" />
      </DATA>
    </COL>
  </ROW>
</xsl:for-each>

答案 1 :(得分:2)

产生所需结果的一种可能的转换是以下

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <!--                                              -->
    <xsl:template match="/*">
      <TABLE>
        <xsl:apply-templates select="*"/>
      </TABLE>
    </xsl:template>
 <!--                                              -->
    <xsl:template match="FUNCTION">
      <ROW>
        <COL><xsl:value-of select="@name"/></COL>
        <COL><xsl:apply-templates select="PARAMETER"/></COL>
        <COL><xsl:apply-templates select="CODE"/></COL>
      </ROW>
    </xsl:template>
 <!--                                              -->
<xsl:template match="PARAMETER">
 <xsl:param name="pDelim" select="';'"/>
 <xsl:value-of select=
 "concat(@name,
         substring($pDelim,
                   1 div not(position() = last()))
                   )"/>
</xsl:template>
</xsl:stylesheet>

将此转换应用于原始XML文档

<SEARCHRESULTS>
    <FUNCTION name="BarGraph">
        <PARAMETER name="numList"></PARAMETER>
        <PARAMETER name="maxValue"></PARAMETER>
        <CODE>Some code</CODE>
    </FUNCTION>
</SEARCHRESULTS>

生成了想要的结果

<TABLE>
   <ROW>
      <COL>BarGraph</COL>
      <COL>numList;maxValue</COL>
      <COL>Some code</COL>
   </ROW>
</TABLE>

请注意 <xsl:template> 相匹配的 PARAMETER 的参数 {{1} } ,可用于指定要用作参数名称列表的分隔符的字符(或字符串)。此分隔符的默认值设置为“;”。

答案 2 :(得分:2)

xsl:apply-templates将是您的答案。它简单而优雅。

<xsl:template match="FUNCTION/PARAMETER">
    <xsl:if test="position() > 1">
        <xsl:text>; </xsl:text> <!-- This is the delimiter -->
    </xsl:if>
    <xsl:value-of select="@name" />
</xsl:template>

然后代替<xsl:value-of select="PARAMETER/@name" />你做到了:

<xsl:apply-templates select="PARAMETER" />

答案 3 :(得分:1)

<xsl:template match="PARAMETER">
    <xsl:value-of select="@name" />
    <xsl:text> </xsl:text>
</xsl:template>

替换当前代码

  <COL><DATA><xsl:value-of select="PARAMETER/@name" /></DATA></COL>

  <COL><DATA><xsl:apply-templates select="PARAMETER"/></DATA></COL>