3

Given that any type other than a node-set cannot be coerced into a node-set, how do we determine,at runtime, if the result of an XPath expression is a node-set? Although I guess it shouldn't matter, I'm using Sablotron for processing. Thanks in advance.

  • Can you explain the situation where it is uncertain whether an expression returns a node-set, or something else? – Tomalak Oct 19 '09 at 11:06
  • In our application, we allow users to specify XPath expressions as custom input data from a document. To implement a function like "containsElement(s,t)", defined as: a. true, if 's' evaluates to a node-set(N) and contains(n,t) is true for any one node(n) in N b. If 's' is not a node-set, the result of evaluating contains(s,t). – macsimus_slackus Oct 19 '09 at 14:48
  • We noticed that the following are not equivalent: 1. s[contains(.,t)] - s has to be a nodeset. For e.g. substring(/books/book/title,1,3)[contains(.,'ABC')] doesn't work 2. contains(s,t) - s need not be a nodeset, but if it is, only the first element is considered for processing Please correct me if I'm wrong, but if we are able to determine whether the input 's' is a node-set, we can choose between using 1 or 2 above. Also, we are using XPath 1.0. Thanks in advance any help! – macsimus_slackus Oct 19 '09 at 14:49
  • But `substring(/books/book/title,1,3)[contains(.,'ABC')]` really does not make much sense. Why would you want to apply a predicate to *anything other* than a node-set? If you want all books that begin with `'ABC'` you'd rather say `/books/book[contains(substring(title, 1, 3), 'ABC')]`, wouldn't you? (Or, `/books/book[starts-with(title, 'ABC')]`, for that matter.) – Tomalak Oct 19 '09 at 16:57
  • What I want to say is this: Any XPath that does not select a node-set is useless by definition, for your context (as I understand it) at least. – Tomalak Oct 19 '09 at 16:59
  • I completely understand what you are saying, but I need to be clear what the problem is. I am enhancing an XSLT rules engine tool which allows the user to select a RHS operand, a LHS operand, and an operator. The objective is to allow a new operator called 'contains' which will leverage XPath's contains() function. The user is allowed to specify as the LHS operand (amongst other things) an XPath expression. We do not know until runtime what the result of the XPath expression entered by the user is... a nodeset or non-nodeset. – macsimus_slackus Oct 19 '09 at 18:04
  • If the users custom XPath expression happens to evaluate to a node-set then applying a predicate to the end of the XPath expression provides the appropriate evaluation of the contains function. (I.E. /books/book/title[contains(.,'ABC')]) However, if the XPath expression is not a node-set then the language does not support the addition of the predicate at the end substring(/books/book/title,1,3)[contains(.,'ABC')], and we would have to default to contains(substring(/books/book/title,1,3), 'ABC'). – macsimus_slackus Oct 19 '09 at 18:05
  • So the question stands, at runtime, knowing that I will need to be able to flex the addition of the predicate, or not, based on what the resulting value of the client defined XPath expression is... is there a way to determine at runtime whether or not the resulting value of an XPath expression is or is not a node-set? – macsimus_slackus Oct 19 '09 at 18:09

1 Answers1

1

You can ask for the maximum position. If it is greater than 1 the result is a list:

max(some/path/position())
ceving
  • 21,900
  • 13
  • 104
  • 178