Re: [xsl] XSLT functions in XPath

Subject: Re: [xsl] XSLT functions in XPath
From: Victor Toni <xsl-list@xxxxxxxxx>
Date: Wed, 11 Oct 2006 02:26:20 +0200
Michael Kay wrote:
>> Actually its there, but the class
>> net.sf.saxon.dom.DOMNodeList seems to be not recognized.
>> As you see in the class net.sf.saxon.dom.DOMObjectModel
>> public boolean isRecognizedNode(Object object) {
>> return object instanceof Node && !(object instanceof
>> NodeOverNodeInfo);
>> }
>> NodeList isn't a recognized class.
> It's not recognized as representing a node, because it doesn't represent a
> node.
> What are you actually trying to do?
Xerces returns ElementImpl when Node.childNodes() is called, which
itself implements Node. Therefore my first guess was, that this might be
the problem.

After further investigation I noticed that Saxon's XPath implementation
(over JAXP) had difficulties to deal with "random" XPath results as
context since "net.sf.saxon.dom.DOMNodeList" implements "NodeList" but
not "Node":

final Document document = documentBuilder.newDocument();

result  =  xpath.evaluate("/root/*)", document, XPathConstants.NODESET);
// works
list  =  xpath.evaluate("('a', 'b', 'c')", document,
XPathConstants.NODESET); // works

list2  =  xpath.evaluate("('a', 'b', 'c')", result,
XPathConstants.NODESET); // throws exception
list3  =  xpath.evaluate("('a', 'b', 'c')", list,
XPathConstants.NODESET); // throws exception

Actually one doesn't need a context for evaluating "list" and "list2"
but the implementation requires it to be non null.
Since "result" (of type net.sf.saxon.dom.DOMNodeList) doesn't lead to a
recognized model, Saxon fails on "list2" while it works with the noop
document for "list".
Because a context is required to evaluate even simple expressions I have
to take the current context which might be a non Node result, this lead
to the observed error.

Since "list" has no more relation to the document by which it has been
created I cannot iterate over "list" and use it as the context for other
XPath expressions.

To give you an idea of what I would like to do:

    <variable name="severities" xpath="('Critical', 'High', 'Medium',
'Low' )"/>

<repeatable target="Severity" xpath="$severities">
        <variable name="severity" xpath="."/>

    <repeatable target="Issue" xpath="//issue[severity = $severity]">
        <data target="ID" xpath="id"/>
        <data target="Description" xpath="description"/>
        <data target="PatchList"
xpath="string-join(patches/patch/patchId, ' ')"/>


Target identifies some object which has to filled either with data or
with children.

In my use case I won't know if the context is required or not since
everything is dynamic but I cannot be sure that it's a "usable" context,
hence all XPath expression must be changed to result in a Node (as the
parent context for its children) and nodesets must be stored inside
This is less convenient than I expected but should do the trick.

Current Thread