How to set the value of a variable in a udf requir

2019-09-04 21:31发布

I'm trying to use a user-defined function in XSLT that repeatedly calls the value of a certain string. That string is based on the outcome of an XPath expression that doesn't change within the span of a single function call. I thought it would be a good idea to assign it to a variable rather than look it up over and over again.

Unfortunately, at least in Saxon's implementation, you cannot use an XPath expression requiring a node inside a function, even one based on an absolute path, without first using a throw-away line to let the function know you are discussing the root document rather than some other one.

So, for example, the following code throws an error:

<xsl:function name="udf:LeafMatch">
<xsl:param name="sID"></xsl:param>
<xsl:variable name="myLeaf" select="/potato/stem[@sessionID=$sID][scc]/scc/@leafnumber"/>

Normally, the solution is just to first call any global variable to give context. For example, the following works inside of an udf ($root is a variable identified with the root node):

<xsl:for-each select="$root">
<xsl:value-of select="/potato/stem[@sessionID=$sID][scc]/scc/@leafnumber"/>
</xsl:for-each>

But this doesn't work when trying to use Xpath to fix the value of a variable because I'm not allowed to put the expression within a for-each.

I also tried using

<xsl:choose><xsl:when select"$root"><xsl:value-of select="/potato/stem[@sessionID=$sID][scc]/scc/@leafnumber"/></xsl:when></xsl:choose>

to give it context, going on what I saw here:http://www.stylusstudio.com/xsllist/200504/post00240.html

That didn't work either.

FWIW, passing the variable into the function is problematic because the Xpath expression used to define "myleaf" depends on the context node, and I don't know how to get Xpath to call one path based on values in the current context node.

For example, in the code calling this function I have something like:

<xsl:for-each select="/potato/stem[eye]">
<leaf = "{udf:LeafMatch(@sessionID)}"/>
</xsl:for-each>

I'm working in the context of a /potato/stem[eye] node and using the udf to look for a /potato/stem[scc] node that has the same value of @sessionID. I don't know how to reference the value of @sessionID from the current context node in the predicate of an XPath searching for other nodes in a completely different part of the XML tree, so I was using a udf to do that. It was working fine until I decided to try to use a variable for the string rather than having the processor look it up each time.

I was trying to avoid going one level deeper (having my function itself call a named template or putting a named template inside my original for-each and having that named template call a function).

So my questions are:

A. For a user-defined function, how do I set a variable that depends on an XPath expression?

B. Is there a snazzy way in Xpath to use values drawn from the current content node in the predicates of the Xpath expression you are trying to test?

1条回答
放我归山
2楼-- · 2019-09-04 22:29

So my questions are:

A. For a user-defined function, how do I set a variable that depends on an XPath expression?

B. Is there a snazzy way in Xpath to use values drawn from the current content node in the predicates of the Xpath expression you are trying to test?

Both questions are quite unclear.

A: I assume you actually mean:

"Inside an xsl:function how do I define a variable that depend on the context node?"

The answer: You can't. By definition there is no context node within an xsl:function. This is defined by the W3C XSLT 2.0 specification in the following way:

"Within the body of a stylesheet function, the focus is initially undefined; this means that any attempt to reference the context item, context position, or context size is a non-recoverable dynamic error. [XPDY0002]"

You can, however, pass as a parameter the intended context node (or just the document node that must be used as current). Or, alternatively, you may refer to a globally defined variable.

B: This question is completely not understandable:

  1. What is "snazzy"?

  2. What is "current content node"? Please, provide an example of a specific task to be accomplished in the wanted "snazzy" way.

查看更多
登录 后发表回答