如何将节点(any)发送到xsl:function?

时间:2009-08-28 04:23:52

标签: xml xslt

我可以将节点发送到XSLT功能吗?例如:

<books>
  <book>
    <author>a1</author>
    <price>10</price>
    <year>2009</year>
  </book>
  <!-- ... -->
</books>

我可以将<book>元素发送到函数 - 在该函数中我想要处理书下的节点(<author><price><year>

我可以创建一个xsl:function,如下所示吗?

 <xsl:function name="util:checkNode" as="xs:boolean">
      <!-- I would like to know xml schema data type for the param -->
       <xsl:param name="nodeP" as="****"/>
  </xsl:function


          If yes, what xsl schema type to the param ? 

看起来我通过说函数而不是xsl来创建很多混淆:函数---- :(

5 个答案:

答案 0 :(得分:8)

我认为你问题的答案是肯定的。您可以将节点发送到XSLT函数。

如果您想知道如何使用as =“”属性的值,您有几个选择。如果您想要非常宽松并接受任何事情,请使用 as =“item()*”

From David Pawson's site

  

item()* ..有点节点集? W3C

     

是的,我同意它看起来很漂亮   毫无意义的不是它。然而。作为   CR,非常重要,尤其如此   如果你想使用类型。并希望   比如生成一个节点集..抱歉   序列,在变量中。

<xsl:variable name="a"
 select="(//h3)[position() < 3]"
 as="item()*"/>
  

这会创建一个你可以破解的变量   很容易使用xpath。即   记住item()*。

     

类型......一些例子。 W3C

     

来自Mike的解释性电子邮件   凯,谢谢迈克。例子:

     

<xsl:param name="x" as="item()"/>

     

参数值可以是任何项目   (即节点或原子值)。但它   必须是单个项目。

     

<xsl:param name="x" as="item()?"/>

     

参数可以是单个项目或   一个空序列

     

<xsl:param name="x" as="item()+"/>

     

参数必须是序列   一个或多个项目 - 空序列   不允许

     

<xsl:param name="x" as="item()*"/>

     

参数可以是任何序列   零个或多个项目 - 这个没有   对其价值的限制。

     

<xsl:param name="x" as="node()*"/>

     

参数可以是任何序列   零个或多个节点

     

<xsl:param name="x" as="xs:atomicValue*"/>

     

参数可以是任何序列   零个或多个原子值(例如   整数,字符串或布尔值。)

     

item()*是最常用的类型   可能,它匹配一切,如   Java中的“对象”。出于这个原因,它   通常可以省略。但不是   总是,例如默认类型   在xsl:variable中不是item()*但是   document-node(),以确保

     

<xsl:variable name="rtf"><a>thing</a> </xsl:variable>

     

继续表现得像XSLT 1.0

     

使用这些来指定参数,   变量类型等。

答案 1 :(得分:0)

XSL并不关心参数是什么。它真的把所有东西视为XML。如果传入文本,则将其视为文本节点。

以下是一个链接示例,供进一步参考。

http://www.w3schools.com/xsl/

<xsl:call-template name="TemplateName">
    <xsl:with-param name="ParamName" select="MyNode/MyNode" />
</xsl:call-template>

<xsl:template name="TemplateName">
    <xsl:param name="ParamName" />
</xsl:template>

答案 2 :(得分:0)

有很多XSLT函数接受节点作为参数。例如,concat的所有参数都可以是节点,例如:

concat(myelement, myelement/@myattribute)

虽然这恰好回答了你提出的问题,但我敢打赌折钱,这不是你想要回答的问题。但是,哎呀,你问了四次,所以你走了。

修改

实际上,属性不是节点;只有元素,文本,注释,处理指令和CDATA部分是节点。但上面的例子仍然正确地回答了这个问题。

答案 3 :(得分:-1)

要添加到ChaosPandion答案,您可能需要在XPath查询中添加node test

<xsl:call-template name="TemplateName">
    <xsl:with-param name="ParamName" select="MyNode/MyNode/node()" />
</xsl:call-template>

<xsl:template name="TemplateName">
    <xsl:param name="ParamName" />
</xsl:template>

正式地说,node()不是一个函数,它是一个测试但可以返回一个类似于XmlNode.InnerXml属性的值。

答案 4 :(得分:-1)

在你的问题中:

  

我可以发送&lt; book&gt;函数的元素 - 在该函数中我想处理book下的节点(&lt; author&gt;,   &LT;价格&gt;或者&lt; year&gt;)

以后评论:

  

我可以使用一个接受节点作为参数的函数吗?

...你要求的是一个功能,但我认为你想要的是book元素的template

当然,您可以通过多种方式执行此操作 - 在for-each循环中,实际上使用with-param等将book节点发送到模板中 - 但这只是一个简单的{ {3}}应该完成你所需要的。模板匹配的是“参数”。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="books">
  <xsl:apply-templates select="book"/>
</xsl:template>

<xsl:template match="book">
    author: <xsl:value-of select="author" />
    price: <xsl:value-of select="price" />
    year: <xsl:value-of select="year" />
</xsl:template>

</xsl:stylesheet>

如果您想对子元素(作者,价格和年份)进行进一步处理,您可以考虑为它们创建模板。请记住,匹配“年份”将匹配所有年元素,即使是出生日期可能有的那些元素。(在这些情况下,您可能希望限制匹配中的XPath或仅将book/year处理保留在图书模板中。)假设您想要使用year执行额外操作。您的图书处理可能会演变成这样的(您现在将每个year节点作为参数传递到年份模板中):

<xsl:template match="book">
    author: <xsl:value-of select="author" />
    price: <xsl:value-of select="price" />
    <xsl:apply-templates select="year" />
</xsl:template>

<xsl:template match="year">
   <xsl:choose>
      <xsl:when test="year &lt; '2000'">
         from a prior century: <xsl:value-of select="." />
      </xsl:when>
      <xsl:otherwise>
         from this century: <xsl:value-of select="." />
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>