On 04/09/07, Florent Georges <[EMAIL PROTECTED]> wrote:
> sebb wrote:
>
> > On 04/09/07, Florent Georges wrote:
>
> > >    bindings:
> > >      u1=uri 1
> > >      u2=uri 2
>
> > >    expression:
> > >      /u1:elem1/u2:elem2
>
> > > to get the deepest element.
>
> > OK, I now understand that XPath requires that the
> > namespace must be (unambiguously) pre-defined; this is not
> > possible when the namespace is declared on a child
> > element.
>
>  What child element?  I speak about an XPath expression and
> the associated set of namespace bindings.  Input documents
> are not relevant here.

I was referring to the input document, see below.

> > > http://xml.apache.org/xalan-j/xpath_apis.html#namespacecontext
>
> > I've had a look at that, but it is a bad example: it is
> > actually not necessary to do any binding in that
> > case.
>
>  ?  Of course it is necessary.  You use the prefixes foo
> and bar.  They have to be bound in one way or another.

See below.

> > This can be seen by using the ApplyXPathDOM or ApplyXPath
> > command-line tests - they work fine.
>
>  Yes.  Because it sets the right bindings when it calls
> selectNodeIterator().  This method takes its binding from
> the context node passed at its first parameter.  In the case
> of ApplyXPath that it the root element of the file (where
> the bindings are declared).

OK, now I understand.

I had not realised that the binding was done that way; it seemed to be
automatic in the document processing.

The JMeter code uses XPathAPI.eval(doc, query).

I just checked the Javadoc

http://xml.apache.org/xalan-j/apidocs/org/apache/xpath/XPathAPI.html#eval(org.w3c.dom.Node,%20java.lang.String)

Which says: "... Using this method, XPath namespace prefixes will be
resolved from the namespaceNode".

However, there is no such parameter.

Further digging shows that what the code actually does is to use the
contextNode as the namespaceNode.

> > Also, there has to be a nicer way to declare namespaces -
> > the example suggests that it is necessary to create ones
> > own (hard-coded) classes.  Surely there is a utility class
> > to do this?
>
>  I don't see the problem.  You put a two-column table in
> the GUI, allowing the user to edit the various bindings (on
> the left the prefix, on the right the associated URI).

That part is fine.

> Then you use something like the following:
>
>    public class JMeterNamespaceContext
>        implements NamespaceContext
>    {
>        // Bindings: keys=prefixes, values=uris
>        public JMeterNamespaceContext(Map<String, String> bindings)
>        {
>            myPrefixToURI = bindings;
>        }
>
>        public String getNamespaceURI(String prefix)
>        {
>            return myBindings.get(prefix);
>        }
>
>        public String getPrefix(String uri)
>        {
>            List<String> prefixes = getURIToPrefix().get(uri);
>            if ( prefixes == null ) {
>                return null;
>            }
>            else {
>                return prefixes.get(0);
>            }
>        }
>
>        public Iterator getPrefixes(String uri)
>        {
>            List<String> prefixes = getURIToPrefix().get(uri);
>            if ( prefixes == null ) {
>                return null;
>            }
>            else {
>                return prefixes.iterator();
>            }
>        }
>
>        private Map<String, List<String>> getURIToPrefix()
>        {
>            if ( myURIToPrefix == null ) {
>                myURIToPrefix = new HashMap<String, List<String>>();
>                for ( String p : bindings.keySet() ) {
>                    List<String> prefixes = myURIToPrefix.get(p);
>                    if ( prefixes == null ) {
>                        prefixes = new ArrayList();
>                        myURIToPrefix.put(p, prefixes);
>                    }
>                    prefixes.add(bindings.get(p));
>                }
>            }
>            else {
>                return myURIToPrefix;
>            }
>        }
>
>        private Map<String, String> myPrefixToURI = null;
>        private Map<String, List<String>> myURIToPrefix = null;
>    }
>

What I was getting at is that the above code could (*should*) be
provided as utility ...

>  This is not tested and you should refer to the javadoc of

... and then it would only have to be tested once ...

> NamespaceContext to see what changes to do to enforce its
> contract, but the (simple) idea is there, IMHO.
>
>  Did I miss something?

No, I think it's mainly my misconceptions ...

>  Regards,

Thanks for the help and information; I think I understand a lot more
about this now.

Reply via email to