Project

Profile

Help

Can't reference directly accessed node() by name

Added by Joe Gori about 11 years ago

I'm trying to access a child Node, with it's parent in a variable $ssRule, the first version statement fails, the second version of the statement works.

I've referenced other nodes in this fashion before and i can reference all the children of the parent in $ssRule up until maxInputValue properly using the same namespace prefix and syntax given below.

it should be noted that ssRule contains a source that was generated with the xdmNode asSource() process as a tinyTree via Proc.newDocumentBuilder()

<xsl:variable name="maxInputValue" select="$ssRule/gpp:maxInputValue"/>
<xsl:variable name="lastElement" select="$ssRule/*[local-name()='maxInputValue']"/>

this also works 
 
<xsl:variable name="nextElement" select="$ssRule/gpp:minInputValue/following-sibling::node()[1]"/>

minInputValue directly precedes maxInputValue in the node Set

if I use a w3 Document for $ssRule it works without issue built from the w3 DocumentBuilder

the document and source are passed in as parameters

to simplify the Xpath, I've used a number of variables to pare the tree into managable pieces (from an xpath syntax perspective) $ssRule is one such variable with the main nodeset being passed in as a parameter

This is probably not enough information to probably tell me what's going on


Replies (11)

Please register to reply

RE: Can't reference directly accessed node() by name - Added by Michael Kay about 11 years ago

You haven't shown any XML, but my inference would be that the node has a local name of maxInputValue and a namespace that isn't the namespace bound to gpp.

Sorry if that's facile, but it's the only thing I can deduce that's consistent with the information given.

When you find the node with one of the techniques that works, what does namespace-uri() applied to that node return?

RE: Can't reference directly accessed node() by name - Added by Joe Gori about 11 years ago

No it's not facile :) , I under stand it was probably not enough info.

Considering the following snippet

        <specialServiceRules>
           <name>Ins</name>
           <displayName>Insured Item</displayName>
           <supported>true</supported>
           <required>false</required>
           <inputValueRequired>true</inputValueRequired>
           <minInputValue>1</minInputValue>
           <maxInputValue>5000</maxInputValue>
        </specialServiceRules>

this is where $ssRule is pointing to in the tree, there is a namespace associated with it in the stylesheet and it has assigned the gpp prefix.

all children are accessible via the referenced style $ssRule/gpp:name except maxInputValue.

the style sheet takes an xml string/document as the source and a passed in rule set which if

it is built through the s9Api, the maxInputValue element in $ssRules is not accessible by name except as stated by name in the previous missive

if the document is built through org.w3c.dom.Document Document Builder it works just fine.

if I change the XML to

        <specialServiceRules>
           <name>Ins</name>
           <displayName>Insured Item</displayName>
           <supported>true</supported>
           <required>false</required>
           <inputValueRequired>true</inputValueRequired>
           <minInputValue>1</minInputValue>
           <mxInputValue>5000</mxInputValue>
        </specialServiceRules>

by deleting an a from the element name maxInputValue and make the corresponding change to my xslt it also works using a s9api source (just tried this) i've been trying various things all day. to try and figure out where the issue is.

RE: Can't reference directly accessed node() by name - Added by Joe Gori about 11 years ago

o and i'm using the saxon-he 9.4.0.7 jar

RE: Can't reference directly accessed node() by name - Added by Michael Kay about 11 years ago

That's got to be a really subtle bug!

I wonder if you've somehow managed to have the XPath expression compiled with one NamePool and the source document built with another. The software tries quite hard to check for this error but there are probably paths where it can go unnoticed. This would generally mean you have more than one Configuration and therefore more than one Processor.

RE: Can't reference directly accessed node() by name - Added by Joe Gori almost 11 years ago

I'm instantiating the Transform with


TransformerFactory transFact = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
Templates templates = transFact.newTemplates(xslSource);

And I'm building the document/ source that's passed as an argument with


                net.sf.saxon.s9api.DocumentBuilder builder = proc.newDocumentBuilder();
                builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);
                InputSource inputSource = new InputSource(new ByteArrayInputStream(XML.getBytes()));
                SAXSource saxSource = new SAXSource(inputSource);
                document = builder.build(saxSource);
                sourceDoc = document.asSource();

I'm assuming that if I am using the s9api interface , I should be using the processor to handle compile and load of the stylesheet as well?

It would make sense now that you mention it that the there would be two processors and two configurations, and hence two NamePools?

A side question are objects created by the processor threadsafe?

RE: Can't reference directly accessed node() by name - Added by Michael Kay almost 11 years ago

Yes, that looks like you've got two NamePools. The question for me is, why isn't Saxon detecting the fact?

You can mix JAXP and s9api if you really want to, because Saxon always gives you the ability to access or set the Configuration object explicitly. For example, you can get the Configuration used by the TransformerFactory (after downcasting to its Saxon implementation class) and then supply it when constructing the Processor.

As for thread-safety - the Executable classes (the compiled stylesheet) are thread-safe. the loaded objects, such as the Transformer/XsltTransformer, are not.

RE: Can't reference directly accessed node() by name - Added by Joe Gori almost 11 years ago

So the saga continues further

I converted over my code to generate the XdmNode and the Style Sheet off of the Same Processor all using the s9api. And it does not work. Not sure where to look further at this point.

RE: Can't reference directly accessed node() by name - Added by Michael Kay almost 11 years ago

See if you can put together a simple repro (or even a complex one) so we can see what's going on and investigate.

RE: Can't reference directly accessed node() by name - Added by Joe Gori almost 11 years ago

I'm going to review it with someone on Monday or Tuesday (as they are currently on vacation) to validate that I am not doing something completely beyond the pale before I send it to you. I'll keep you posted as reports warrant!

RE: Can't reference directly accessed node() by name - Added by Joe Gori almost 11 years ago

I got it to work,

I had converted it over (or so I thought) to use the same processor. It wasn't. The code to generate the XdmNode from the XML string was still using a local processor. Once I made it use the same processor, the error went away.

Is the DocumentBuilder thread-safe?

RE: Can't reference directly accessed node() by name - Added by Michael Kay almost 11 years ago

Glad you sorted it.

The DocumentBuilder should be thread-safe provided you don't actually change its properties (eg, by doing setTreeModel()) while a document is being built.

    (1-11/11)

    Please register to reply