如何选择xpath返回类型?

时间:2012-08-10 19:02:46

标签: xslt xpath documentfragment

我有xpath查询:

        <xsl:variable name="fbids">
            <xsl:sequence select="
                feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']]
                /object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/>
        </xsl:variable>

此查询不会将一系列匹配节点作为序列本身返回,而是将它们作为单个#documentfragment的子节点返回。即使没有元素满足此查询,$ fbids仍设置为空的#documentfragment。

这会搞砸我的代码,而下面的循环,而不是每个匹配的元素迭代一次,为#documentfragment运行一次,就是这样。如何强制它返回一个漂亮的元素()*类型?

谢谢!

2 个答案:

答案 0 :(得分:2)

XSLT 2.0中变量的默认类型是documentfragment。如果您希望它是一系列元素,则添加as属性并指定序列类型。您还可以使用select属性,而不是嵌套的序列元素:

<xsl:variable name="fbids" as="element()*" select="
            feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']]
             /object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/>

答案 1 :(得分:2)

      <xsl:variable name="fbids">
          <xsl:sequence select="
              feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']]
              /object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/>
      </xsl:variable>
     

此查询不会将一系列匹配节点作为序列返回   本身,它将它们作为单个#documentfragment的子项返回。

是的,因为变量体内有一个序列,而变量没有指定类型。在这种情况下,默认类型为:document-node()

<强>解决方案

指定不带正文的变量,并在select的{​​{1}}属性中提供XPath表达式:

xsl:variable

使用<xsl:variable name="fbids" select=" feature_relationship[type_id/cvterm[name='molec_deletes' or name='deletes']] /object_id/feature/feature_synonym/synonym_id/synonym/synonym_sgml"/> 属性指定变量的所需类型仍然是一个好习惯。

当在其主体内动态创建变量(一系列元素)的值时,完整答案也必须涵盖

再次指定变量的类型是解决方案的关键

这是一个小而完整的例子:

as

对以下XML文档应用此转换时:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">

  <xsl:variable name="vMapped" as="element()*">
    <xsl:for-each select="num">
      <num><xsl:value-of select=".*2"/></num>
    </xsl:for-each>
  </xsl:variable>

  <xsl:for-each select="$vMapped">
   <xsl:sequence select="."/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

名为<nums> <num>01</num> <num>02</num> <num>03</num> <num>04</num> <num>05</num> <num>06</num> <num>07</num> <num>08</num> <num>09</num> <num>10</num> </nums> 的变量在其正文中获取其动态创建的值。其余代码成功地将此变量用作元素序列 - 访问此序列中的每个元素并将其复制到输出中:

$vMapped