You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Scott Boag/CAM/Lotus <Sc...@lotus.com> on 2000/06/08 20:22:05 UTC

RE: XPathAPI.selectSingleNode (& bug in XPathAPI.eval)

> If my <schema> and <simpleType> have no namespace declaration, aren't
they resolved by the default xmlns="" namespace?

Yes.

> I would anticipate that selectSingleNode would see no namespace in my
"simpleType" xpath statement, and would use the default namespace declared
in doc.getDocumentElement() to resolve "simpleType".

No, that's where you make your mistake.  You can not use the default
namespace inside xpath (there are various good reasons for this).  It has
to be specifically declared with a prefix, and the prefix has to be used in
the XPath.

> So is there any way to call selectSingleNode without changing my xml
elements to include the specific xsd: prefix?

Yes.  But you have to have the prefixes in you XPath expression resolve in
a different tree than your input XML, and then use prefixes in the
expression.

An easy way to do this is something like:

        // Use the simple XPath API to select a node.
        StringReader nsReader = new StringReader("<x xmlns:xs
='http://www.w3.org/1999/XMLSchema'/>");
        parser.parse(new InputSource(nsReader));
        Node nsSpace = parser.getDocument().getDocumentElement();
        nl = XPathAPI.selectNodeList(root, "xs:name", nsSpace);

...for instance.  HOWEVER, when I did the test for this, I found a bug in
the eval code inside XPathXPI.java in the sample.  Please replace the eval
function with this:

  public static XObject eval(Node contextNode, String str, Node
namespaceNode)
    throws SAXException
  {
    // Since we don't have a XML Parser involved here, install some default
support
    // for things like namespaces, etc.
    // (Changed from: XPathSupportDefault xpathSupport = new
XPathSupportDefault();
    //    because XPathSupportDefault is weak in a number of areas...
perhaps
    //    XPathSupportDefault should be done away with.)
    XPathSupport xpathSupport = new XMLParserLiaisonDefault();

    if(null == namespaceNode)
      namespaceNode = contextNode;

    // Create an object to resolve namespace prefixes.
    // XPath namespaces are resolved from the input context node's document
element
    // if it is a root node, or else the current context node (for lack of
a better
    // resolution space, given the simplicity of this sample code).
    PrefixResolverDefault prefixResolver = new PrefixResolverDefault
((namespaceNode.getNodeType() == Node.DOCUMENT_NODE)
                                                         ?
((Document)namespaceNode).getDocumentElement() :
                                                           namespaceNode);

    // Create the XPath object.
    XPath xpath = new XPath();

    // Create a XPath parser.
    XPathProcessorImpl parser = new XPathProcessorImpl(xpathSupport);
    parser.initXPath(xpath, str, prefixResolver);

    // Execute the XPath, and have it return the result
    return xpath.execute(xpathSupport, contextNode, prefixResolver);
  }

I don't think this added to your confusion, but maybe it did.  If so,
sorry...

-scott




                                                                                                                            
                    "Albert, Kevin"                                                                                         
                    <kjalbert@software.roc        To:     "'xalan-dev@xml.apache.org'" <xa...@xml.apache.org>           
                    kwell.com>                    cc:     (bcc: Scott Boag/CAM/Lotus)                                       
                                                  Subject:     RE: XPathAPI.selectSingleNode                                
                    06/05/2000 02:30 PM                                                                                     
                    Please respond to                                                                                       
                    xalan-dev                                                                                               
                                                                                                                            
                                                                                                                            



Thanks for your reply, but I'm sorry to say I am still confused.  If you
could help me understand this I'd appreciate it.

If I change my xml so
<schema xmlns="http://www.w3.org/1999/XMLSchema"> becomes <xsd:schema
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
and <simpleType> becomes <xsd:simpleType>,
then XPathAPI.selectSingleNode(doc.getDocumentElement(), "xsd:simpleType")
returns the simpleType node.

If my <schema> and <simpleType> have no namespace declaration, aren't they
resolved by the default xmlns="" namespace?
I would anticipate that selectSingleNode would see no namespace in my
"simpleType" xpath statement, and would use the default namespace declared
in doc.getDocumentElement() to resolve "simpleType".  But this does not
appear to be the case ...

So is there any way to call selectSingleNode without changing my xml
elements to include the specific xsd: prefix?

I hope you understand my question, and where my confusion is.  If not,
please let me know.  If you can explain what is happening when a default
namespace is used I would very much appreciate it.

Regards,
Kevin Albert

-----Original Message-----
From: Scott Boag/CAM/Lotus [mailto:Scott_Boag@lotus.com]
Sent: Sunday, June 04, 2000 12:45 PM
To: xalan-dev@xml.apache.org
Subject: Re: XPathAPI.selectSingleNode



I'm not sure if someone else has already answered this...

You have a default namespace on your input xml.  So you should read your
"simpleType" element name as something like
"http://www.w3.org/1999/XMLSchema#simpleType".  You'll need to use one of
the XPathAPI's that take a namespace resolver, so you can do something like
Node optionTypeNode =
XPathAPI.selectSingleNode(docOption.getDocumentElement(),"schema:simpleType
[@name='actionType']");

And have 'schema:' map to "http://www.w3.org/1999/XMLSchema".

-scott





                    "Albert, Kevin"

                    <kjalbert@software.roc        To:     "Xalan-Dev
(E-mail)" <xa...@xml.apache.org>
                    kwell.com>                    cc:     (bcc: Scott
Boag/CAM/Lotus)
                                                  Subject:
XPathAPI.selectSingleNode
                    06/02/2000 02:12 PM

                    Please respond to

                    xalan-dev






I'm using Cocoon 1.7.3 (with Xalan 1.0.1) on Tomcat, and am trying to use
XPathAPI to select a specific node in an XML document ... but am having
trouble getting selectSingleNode to work.
I could just use the DOM getElementsByTagName and then verify that I've got
the desired element node, but I'd rather select it directly with
selectSingleNode.
Any suggestions/comments would be very appreciated.

Regards,
Kevin Albert


I've got the following schema doc:

<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://rsi-logic2k/specweb" xmlns="
http://www.w3.org/1999/XMLSchema" xmlns:rsi-fdd="http://rsi-logic2k/specweb
">
   <simpleType base="string" name="actionType">
      <enumeration value="send">
         <annotation><documentation>to transport from one location to
another location</documentation></annotation>
      </enumeration>
   </simpleType>
</schema>



and in the following XSP page, I would like to select the simpleType[@name
='actionType'] node using XPathAPI.selectSingleNode():

<?xml version="1.0"?>
<?cocoon-process type="xsp"?>
<xsp:page language="java" xmlns:xsp="http://www.apache.org/1999/XSP/Core">

  <xsp:structure>
    <xsp:include>org.apache.xerces.dom.*</xsp:include>
    <xsp:include>org.apache.xerces.parsers.*</xsp:include>
    <xsp:include>org.apache.xml.serialize.*</xsp:include>
    <xsp:include>org.w3c.dom.*</xsp:include>
    <xsp:include>XPathAPI</xsp:include>
  </xsp:structure>

  <page>
    <xsp:logic xml:space="preserve">
      String paramOptionType = "Action";
      String optionFileSpec = "webapps/docroot/specweb/features/fdd/" +
paramOptionType + "s/index.xsd";
      InputSource optionFile = new InputSource(optionFileSpec);
      DOMParser parser = new DOMParser();
      parser.parse(optionFile);
      Document docOption = parser.getDocument();

<!-- This returns null -->
      Node optionTypeNode =
XPathAPI.selectSingleNode(docOption.getDocumentElement(),"simpleType[@name
='actionType']");
<!-- This returns null -->
      Node optionTypeNode =
XPathAPI.selectSingleNode(docOption.getDocumentElement(),"simpleType");
<!-- This returns null -->
      Node optionTypeNode =
XPathAPI.selectSingleNode(docOption.getDocumentElement(),"//simpleType");
<!-- This returns null -->
      Node optionTypeNode = docOption.getElementsByTagName("simpleType
[@name='actionType']");

<!-- This returns the simpleType node -->
      Node optionTypeNode =
XPathAPI.selectSingleNode(docOption.getDocumentElement(),"child::*[1]");
<!-- This returns the simpleType node -->
      Node optionTypeNode = docOption.getElementsByTagName
("simpleType").item(0);

    </xsp:logic>
  </page>
</xsp:page>