过滤属性上的xsl:value-of

时间:2009-12-16 06:24:15

标签: xml xslt

我目前有一个这样的XML文档:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="./transform.xsl"?>
<Documentation><Tables>
<TABLE TABLE_NAME="FirstTable">
  <COLUMN COLUMN_NAME="FirstColumn" ORDINAL_POSITION="1" IS_NULLABLE="NO" DATA_TYPE="int" />
  <COLUMN COLUMN_NAME="SecondColumn" ORDINAL_POSITION="2" IS_NULLABLE="NO" DATA_TYPE="int" />
</TABLE>

...

</Tables><Comments>
<COMMENT ForTable="FirstTable" ForColumn="FirstColumn">Description of FirstColumn</COMMENT>
</Comments></Documentation>

我的问题是,在循环表和列时如何获取COMMENT的值?我有:

<xsl:for-each select="//TABLE">
  ...
  <xsl:for-each select="COLUMN">
    ...
    <xsl:value-of select="//COMMENT[@ForTable = @TABLE_NAME and @ForColumn=@COLUMN_NAME]" />

但这不起作用。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

它不起作用,因为select-value的值是“获取所有注释的值,其ForTable属性与其TABLE NAME属性具有相同的值,并且其ForColumn属性与其COLUMN NAME属性具有相同的值”。

尝试类似

的内容
<xsl:for-each select="//TABLE">
    <xsl:variable name="table_name" select="@TABLE_NAME"/>
    ...
    <xsl:for-each select="COLUMN">
        <xsl:variable name="column_name" select="@COLUMN_NAME"/>
        ...
        <xsl:value-of select="//COMMENT[@ForTable=$table_name and @ForColumn=$column_name]" />

答案 1 :(得分:1)

解决此问题的另一个变体是:

<xsl:for-each select="/Documentation/Tables/TABLE">
  <!-- select all comments for the current table name… -->
  <xsl:variable name="$comments" select="
    /Documentation/Comments/COMMENT[@ForTable = current()/@TABLE_NAME]
  "/>

  <xsl:for-each select="COLUMN">
    <!-- …of those, select the one with the current column name -->
    <xsl:value-of select="
      $comments[@ForColumn = current()/@COLUMN_NAME]
    " />
  </xsl:for-each>
</xsl:for-each>

好处是:

  • 你只需要一个变量,而不是两个
  • 内部for-each可以更快地运行,因为它正在查看较小的预过滤数据集

请注意:

  • 我使用current()来引用XPath谓词中的XSLT上下文节点。
  • 我在XPath表达式中避免使用//,因为它具有非常糟糕的性能特征,如果可能,不应该使用它。您的输入文档结构意味着不需要//