There are two reasons your code doesn't work: firstly there are no attributes on the document node (it isn't an element), and secondly (as you suggested), namespaces are represented as namespace nodes rather than attribute nodes. It helps to have an understanding of the XPath data model here, because the NodeInfo interface mirrors it very closely.
 
To get from the document node to the outermost element you can do:
 
NodeInfo docElement = oDocument.iterateAxis(Axis.CHILD, NodeKindTest.ELEMENT).next();
 
and then change
 
AxisIterator iterAtts = oDocument.iterateAxis(Axis.ATTRIBUTE);
to
 
AxisIterator iterAtts = docElement.iterateAxis(Axis.NAMESPACE);
Michael Kay
http://www.saxonica.com/
 
 


From: Kevin Burges [mailto:KevinBurges@formedix.com]
Sent: 11 December 2008 02:41
To: Mailing list for the SAXON XSLT and XQuery processor
Subject: Re: [saxon] Passing NodeSet parameter from Java


I think I'm almost there. There's one bit of code that I haven't managed to get yet though. I'm trying to parse a document and do a search of all the namespaces on the root node to find one that begins with a certain string, then get that value. Here's the code I was using before:

                        Document oDoc = oParser.getDocument();
                        NamedNodeMap oAtts = oDoc.getDocumentElement().getAttributes();
                        for (int nCur = 0; nCur < oAtts.getLength(); nCur++)
                        {
                                if (oAtts.item(nCur).getNodeValue().startsWith(XMLWriter.MY_NS_ROOT))
                                {
                                        m_sMyNamespaceURI = oAtts.item(nCur).getNodeValue();
                                        break;
                                }
                        }

I tried changing that to this:

                        NodeInfo oDocument = m_oSession.getETFManager().getConfiguration().buildDocument(new StreamSource(m_oTransformFile));
                        AxisIterator iterAtts = oDocument.iterateAxis(Axis.ATTRIBUTE);
                        while (true)
                        {
                                NodeInfo oAtt = (NodeInfo)iterAtts.next();
                                if (oAtt == null)        break;
                                if (oAtt.getStringValue().startsWith(XMLWriter.MY_NS_ROOT))
                                {
                                        m_sMyNamespaceURI = oAtt.getStringValue();
                                        break;
                                }
                        }

But oAtt is always null. I'm trying to get it to recognise something like:   xmlns:myns="http://my.root/anyextension"

I think I read somewhere that the Attribute axis does not contain namespace nodes so I tried various things to do with NamePools but I couldn't get anything working. How would I get the same effect I had before?


Cheers,
Kevin



From: "Michael Kay" <mike@saxonica.com>
To: "'Mailing list for the SAXON XSLT and XQuery processor'" <saxon-help@lists.sourceforge.net>
Date: 09/12/2008 23:36
Subject: Re: [saxon] Passing NodeSet parameter from Java





I'm not sure where you went wrong trying to use the interfaces in package sxpath. I would think this is the right way to go on this. You can use it something like this:
 
XPathEvaluator xpath = new XPathEvaluator(config);
xpath.setNamespaceResolver(...);
XPathExpression exp = xpath.createExpression("//item");
NodeInfo doc = config.build(xmlSource);
XPathDynamicContext context = exp.createDynamicContext(doc);
SequenceIterator nodes = exp.iterate(context);
while (true) {
  NodeInfo node = (NodeInfo)nodes.next();
  if (node == null) break;
  ... process one node ...
}
 
Here config is the Configuration used by the TransformerFactory. Best thing is to create it yourself:
 
Configuration config = new Configuration();
TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl(config);
Templates templates = factory.newTemplates(xslSource);
Transformer transformer = templates.newTransformer();
transformer.transform(doc, ....);
 
(the above works because Saxon's NodeInfo implements the JAXP Source interface).
 
In the code you've shown below, you're using a DOM rather than a Saxon TinyTree, which will be a lot slower. If that's what you want to do, however, you can pass the DOM document as the input to the transformation by wrapping it in a javax.xml.transform.dom.DOMSource.
 
Hope this helps!
 
Michael Kay
Saxonica


From: Kevin Burges [mailto:KevinBurges@formedix.com]
Sent:
09 December 2008 12:26
To:
Mailing list for the SAXON XSLT and XQuery processor
Subject:
Re: [saxon] Passing NodeSet parameter from Java



I managed to get it working using s9api using java 1.6.0. It was superbly fast which was great, but I do need to get it working on 1.4.2 at the moment. To that end I tried to change my code to use the sxpath classes. This seemed like it might work, then i couldn't figure out how to get the xpath to return a nodeset, I could only get it to give me a string.


I then tried changing back to my original code using jaxen, but trying to not load the document twice. Here's the gist of the orginal code again:

       

                       System.setProperty(
"javax.xml.transform.TransformerFactory",
                                                       
"net.sf.saxon.TransformerFactoryImpl");
                       System.setProperty(
"javax.xml.parsers.DocumentBuilderFactory",
                                               
"net.sf.saxon.dom.DocumentBuilderFactoryImpl");
               Source xslSource =
new StreamSource(oXSLFile);
              Source xmlSource =
new StreamSource(oXMLFile);

              TransformerFactory oTransFactory = TransformerFactory.newInstance();

              Transformer oTransformer = oTransFactory.newTransformer(xslSource);

             
              Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(oXMLFile);


              for (however many times)

              {

                      org.jaxen.dom.XPath oPath =
new org.jaxen.dom.XPath(sElementPath);
                      oPath.setNamespaceContext(
new ETFTransform.TransformNamespaceResolver(oTransform.getODMNamespaceURI()));        
                      oTransformer.setParameter(VISTransform.
SELECTED_ELEMENTS, oPath.selectNodes(doc));
                      oTransformer.transform(xmlSource,
new StreamResult(new FileOutputStream(oOutput)));
              }


So I have a tree for "doc" - is this a TinyTree? If not, how do I get it to use TinyTree? I tried using doc as the input to transform() to avoid reparsing the input but it won't let me pass a Document, it needs a Source. Can I get it to use the tree I already have somehow?


I don't know why I'm finding this stuff so hard but it's very confusing trying to work our what's going on and what classes are actually being used.


Cheers,
Kevin

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/_______________________________________________
saxon-help mailing list archived at
http://saxon.markmail.org/
saxon-help@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help