Discussion:
[XOM-interest] XOM 1.2.8 released
Elliotte Rusty Harold
2012-05-12 21:11:35 UTC
Permalink
I've posted XOM 1.2.8 in the usual location:

http://www.xom.nu/

This release fixes several bugs in XPath processing that have shown up
in the last month or two, including a nasty incompatibility with Java
7 that could throw an IllegalArgumentException when evaluating
expression that select attributes with a union operator. If you use
XPath at all, I recommend you upgrade at your earliest convenience.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Regier Avery J
2012-05-14 14:44:39 UTC
Permalink
This release resulted in a surprising failure for me. I've been successfully giving a prefix to the default namespace of a document using:

XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
context.addNamespace("a", context.lookup(""));

This now fails because the lookup results in a null. Here's the test case.

package com.deere.axiom.rest.followpass;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.io.StringReader;

import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Nodes;
import nu.xom.ParsingException;
import nu.xom.ValidityException;
import nu.xom.XPathContext;

import org.junit.Test;


public class ERHTest {

// This test fails with
// nu.xom.XPathException: XPath error: Cannot resolve namespace prefix 'a'
@Test
public void testNotWithNamespaceGenericLookup() throws ValidityException, ParsingException, IOException {
Document doc = new Builder().build(new StringReader("<hi xmlns='there://mr.space/alien'/>"));
XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
context.addNamespace("a", context.lookup(""));
Nodes query = doc.query("//*[not(self::a:human)]", context);
assertEquals(1, query.size());
}

}

Avery J. Regier
RegierAveryJ at JohnDeere.com

-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Elliotte Rusty Harold
Sent: Saturday, May 12, 2012 4:12 PM
To: XOM interest
Subject: [XOM-interest] XOM 1.2.8 released

I've posted XOM 1.2.8 in the usual location:

http://www.xom.nu/

This release fixes several bugs in XPath processing that have shown up
in the last month or two, including a nasty incompatibility with Java
7 that could throw an IllegalArgumentException when evaluating
expression that select attributes with a union operator. If you use
XPath at all, I recommend you upgrade at your earliest convenience.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Michael Kay
2012-05-14 15:11:05 UTC
Permalink
Post by Regier Avery J
XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
context.addNamespace("a", context.lookup(""));
It looks as if a bug has been fixed. It should not be possible to bind a
prefix to the "null namespace".


Michael Kay
Saxonica
Regier Avery J
2012-05-14 17:49:24 UTC
Permalink
This is a non-null namespace associated with the whole document, which is unprefixed at the start. See the test document.

Document doc = new Builder().build(new StringReader("<hi xmlns='there://mr.space/alien'/>"));
XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
context.addNamespace("a", context.lookup(""));
Nodes query = doc.query("//*[not(self::a:human)]", context);

I am trying to achieve a single xpath statement that works regardless of the namespace used. This should be achievable (IMHO). Even if you think it shouldn't be done, it's the wrong fix, since looking up the default namespace in the context should work.

Avery J. Regier
IVS Solutions Infrastructure Technical Architect
Work: 515 331-9905 / Cell: 309 781-1366
RegierAveryJ at JohnDeere.com


-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Michael Kay
Sent: Monday, May 14, 2012 10:11 AM
To: xom-interest at lists.ibiblio.org
Subject: Re: [XOM-interest] XOM 1.2.8 released
Post by Regier Avery J
XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
context.addNamespace("a", context.lookup(""));
It looks as if a bug has been fixed. It should not be possible to bind a
prefix to the "null namespace".


Michael Kay
Saxonica
Elliotte Rusty Harold
2012-05-14 17:54:56 UTC
Permalink
On Mon, May 14, 2012 at 10:49 AM, Regier Avery J
I am trying to achieve a single xpath statement that works regardless of the namespace used. ?This should be achievable (IMHO). ?Even if you think it shouldn't be done, it's the wrong fix, since looking up the default namespace in the context should work.
Unprefixed names in XPath expressions are never (modulo bugs like the
one you were depending on) in any namespace.

You can have an XPath expression that works regardless of the
namespace, but it requires some ugly tricks like *:name and explicitly
querying the local-name() of nodes.

IN general, though, why would you want to do that? Outside of the true
ugliness of HTML/XHTML, I've never really seen a need for writing one
expression to apply regardless of namespaces. At one point over a
decade ago people were suggesting that namespaces should change with
each version of an XML vocabulary, which might have made this useful;
but it was soon realized that this was a very bad idea.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Michael Kay
2012-05-14 19:56:29 UTC
Permalink
At one point over a decade ago people were suggesting that namespaces
should change with each version of an XML vocabulary, which might have
made this useful; but it was soon realized that this was a very bad idea.

Unfortunately in the XML world there are many bad ideas that seem to be
widely deployed, and this is one of them. Developers often have to cope
with the mess left behind by XML document designers who should have
known better. (Some of the XML document designers haven't written a line
of code for 20 years, so it's not surprising this happens...)

Michael Kay
Saxonica
Elliotte Rusty Harold
2012-05-14 17:49:28 UTC
Permalink
As Michael surmised, that's a deliberate bug fix. You should no longer
need to bind anything to the default namespace.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Regier Avery J
2012-05-14 17:55:18 UTC
Permalink
Yet I can still do it.

public void testNotWithNamespace() throws ValidityException, ParsingException, IOException {
Document doc = new Builder().build(new StringReader("<hi xmlns='there://mr.space/alien'/>"));
XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
context.addNamespace("a", doc.getRootElement().getNamespaceURI());
Nodes query = doc.query("//*[not(self::a:human)]", context);
assertEquals(1, query.size());
}


I am quite happy that this now works:


Avery J. Regier
IVS Solutions Infrastructure Technical Architect
Work: 515 331-9905 / Cell: 309 781-1366
RegierAveryJ at JohnDeere.com


-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Elliotte Rusty Harold
Sent: Monday, May 14, 2012 12:49 PM
To: XOM API for Processing XML with Java
Subject: Re: [XOM-interest] XOM 1.2.8 released

As Michael surmised, that's a deliberate bug fix. You should no longer
need to bind anything to the default namespace.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Elliotte Rusty Harold
2012-05-14 18:43:43 UTC
Permalink
On Mon, May 14, 2012 at 10:55 AM, Regier Avery J
Post by Regier Avery J
Yet I can still do it.
Yes, what you can't now do (and used to be able to) is bind the
null/empty prefix to a namespace URI.

The prefixes in XPath expressions do not have to be the same as the
prefixes (or lack thereof) in the queried document.
Post by Regier Avery J
? ? ? ?public void testNotWithNamespace() throws ValidityException, ParsingException, IOException {
? ? ? ? ? ? ? ?Document doc = new Builder().build(new StringReader("<hi xmlns='there://mr.space/alien'/>"));
? ? ? ? ? ? ? ?XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
? ? ? ? ? ? ? ?context.addNamespace("a", doc.getRootElement().getNamespaceURI());
? ? ? ? ? ? ? ?Nodes query = doc.query("//*[not(self::a:human)]", context);
? ? ? ? ? ? ? ?assertEquals(1, query.size());
? ? ? ?}
Avery J. Regier
IVS Solutions Infrastructure Technical Architect
Work: 515 331-9905 / Cell: 309 781-1366
RegierAveryJ at JohnDeere.com
-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Elliotte Rusty Harold
Sent: Monday, May 14, 2012 12:49 PM
To: XOM API for Processing XML with Java
Subject: Re: [XOM-interest] XOM 1.2.8 released
As Michael surmised, that's a deliberate bug fix. You should no longer
need to bind anything to the default namespace.
--
Elliotte Rusty Harold
elharo at ibiblio.org
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
--
Elliotte Rusty Harold
elharo at ibiblio.org
Regier Avery J
2012-05-14 20:11:03 UTC
Permalink
Sorry, the previous was accidentally sent before I finished it.

I am quite happy that this now works:
@Test
public void testNotWithDefaultNamespace() throws ValidityException, ParsingException, IOException {
Document doc = new Builder().build(new StringReader("<hi xmlns='there://mr.space/alien'/>"));
XPathContext context = XPathContext.makeNamespaceContext(doc.getRootElement());
Nodes query = doc.query("//*[not(self::human)]", context);
assertEquals(1, query.size());
}
The prefixes in XPath expressions do not have to be the same as the prefixes (or lack thereof) in the queried document.
By this statement it seems that I should be able to create an alias for a namespace that currently lacks one. Why make it hard?
IN general, though, why would you want to do that? Outside of the true ugliness of HTML/XHTML, I've never really seen a need for writing one expression to apply regardless of namespaces.
My immediate use is to translate from a simplified syntax sent over URLs to transform the document being returned from that URL. The client is always giving the path in the namespace associated with the one document returned. The service knows what those namespaces are.

I am specifically attempting to implement embed/fields for REST services as presented in
REST API Design Rulebook by Mark Mass?
(O'Reilly). Copyright 2012 Mark Mass?, 978-1-449-31050-9
Chapter 6, pp 73-77, "Response Representation Composition"


I am working through trying to use the new XOM and make all my tests pass again. It really threw a spanner in the works.


Avery J. Regier
RegierAveryJ at JohnDeere.com


-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Elliotte Rusty Harold
Sent: Monday, May 14, 2012 12:49 PM
To: XOM API for Processing XML with Java
Subject: Re: [XOM-interest] XOM 1.2.8 released

As Michael surmised, that's a deliberate bug fix. You should no longer
need to bind anything to the default namespace.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Michael Kay
2012-05-14 20:34:38 UTC
Permalink
Post by Regier Avery J
By this statement it seems that I should be able to create an alias
for a namespace that currently lacks one. Why make it hard?

It would be rather nice if we had pure symmetry in namespace bindings,
so you could bind the "null" prefix to either a "real" namespace or the
"null" namespace, and bind a "real" prefix to either a "real" namespace
or the "null" namespace. Unfortunately that isn't the way. Of these four
combinations, XML only allows three - it doesn't allow you to bind a
real prefix to the null namespace; and XPath 1.0 only allows two - it
doesn't allow you to bind a null prefix to a real namespace. XPath 2.0
does allow you to bind a null prefix to a real namespace (the "default
namespace for elements and types"), but it still doesn't allow the
fourth option, a real prefix bound to a null namespace.

There are a number of reasons for this asymmetry, none of them in my
mind very good reasons, but unfortunately there is a lot of emotional
baggage associated with namespaces, part of which is the insistence in
some quarters that what I call the "null" namespace is not actually a
namespace at all, but something quite different. The fact that the
engineering would be more convenient if we treated it as a namespace
that happens to have no name doesn't carry much weight with those who
attach metaphysical significance (aka "semantics") to such matters.

Michael Kay
Saxonica
Post by Regier Avery J
IN general, though, why would you want to do that? Outside of the true ugliness of HTML/XHTML, I've never really seen a need for writing one expression to apply regardless of namespaces.
My immediate use is to translate from a simplified syntax sent over URLs to transform the document being returned from that URL. The client is always giving the path in the namespace associated with the one document returned. The service knows what those namespaces are.
I am specifically attempting to implement embed/fields for REST services as presented in
REST API Design Rulebook by Mark Mass?
(O'Reilly). Copyright 2012 Mark Mass?, 978-1-449-31050-9
Chapter 6, pp 73-77, "Response Representation Composition"
I am working through trying to use the new XOM and make all my tests pass again. It really threw a spanner in the works.
Avery J. Regier
RegierAveryJ at JohnDeere.com
-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Elliotte Rusty Harold
Sent: Monday, May 14, 2012 12:49 PM
To: XOM API for Processing XML with Java
Subject: Re: [XOM-interest] XOM 1.2.8 released
As Michael surmised, that's a deliberate bug fix. You should no longer
need to bind anything to the default namespace.
Regier Avery J
2012-05-14 20:44:15 UTC
Permalink
It seems to be lost here that I am not attempting to bind to the null namespace. I am attempting to bind a prefix to a non-null namespace that currently has no prefix because the document did not specify it with one.

- Avery
Post by Michael Kay
Post by Regier Avery J
By this statement it seems that I should be able to create an alias
for a namespace that currently lacks one. Why make it hard?
It would be rather nice if we had pure symmetry in namespace bindings,
so you could bind the "null" prefix to either a "real" namespace or the
"null" namespace, and bind a "real" prefix to either a "real" namespace
or the "null" namespace. Unfortunately that isn't the way. Of these four
combinations, XML only allows three - it doesn't allow you to bind a
real prefix to the null namespace; and XPath 1.0 only allows two - it
doesn't allow you to bind a null prefix to a real namespace. XPath 2.0
does allow you to bind a null prefix to a real namespace (the "default
namespace for elements and types"), but it still doesn't allow the
fourth option, a real prefix bound to a null namespace.
There are a number of reasons for this asymmetry, none of them in my
mind very good reasons, but unfortunately there is a lot of emotional
baggage associated with namespaces, part of which is the insistence in
some quarters that what I call the "null" namespace is not actually a
namespace at all, but something quite different. The fact that the
engineering would be more convenient if we treated it as a namespace
that happens to have no name doesn't carry much weight with those who
attach metaphysical significance (aka "semantics") to such matters.
Michael Kay
Saxonica
Post by Regier Avery J
IN general, though, why would you want to do that? Outside of the true ugliness of HTML/XHTML, I've never really seen a need for writing one expression to apply regardless of namespaces.
My immediate use is to translate from a simplified syntax sent over URLs to transform the document being returned from that URL. The client is always giving the path in the namespace associated with the one document returned. The service knows what those namespaces are.
I am specifically attempting to implement embed/fields for REST services as presented in
REST API Design Rulebook by Mark Mass?
(O'Reilly). Copyright 2012 Mark Mass?, 978-1-449-31050-9
Chapter 6, pp 73-77, "Response Representation Composition"
I am working through trying to use the new XOM and make all my tests pass again. It really threw a spanner in the works.
Avery J. Regier
RegierAveryJ at JohnDeere.com
-----Original Message-----
From: xom-interest-bounces at lists.ibiblio.org [mailto:xom-interest-bounces at lists.ibiblio.org] On Behalf Of Elliotte Rusty Harold
Sent: Monday, May 14, 2012 12:49 PM
To: XOM API for Processing XML with Java
Subject: Re: [XOM-interest] XOM 1.2.8 released
As Michael surmised, that's a deliberate bug fix. You should no longer
need to bind anything to the default namespace.
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
Elliotte Rusty Harold
2012-05-14 20:50:22 UTC
Permalink
On Mon, May 14, 2012 at 1:44 PM, Regier Avery J
Post by Regier Avery J
It seems to be lost here that I am not attempting to bind to the null namespace. I am attempting to bind a prefix to a non-null namespace that currently has no prefix because the document did not specify it with one.
You should be able to do that. Let me take another look at your code.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Elliotte Rusty Harold
2012-05-14 20:51:55 UTC
Permalink
On Mon, May 14, 2012 at 1:50 PM, Elliotte Rusty Harold
Post by Elliotte Rusty Harold
On Mon, May 14, 2012 at 1:44 PM, Regier Avery J
Post by Regier Avery J
It seems to be lost here that I am not attempting to bind to the null namespace. I am attempting to bind a prefix to a non-null namespace that currently has no prefix because the document did not specify it with one.
That doesn't look like what your code is doing. See here:

context.addNamespace("a", context.lookup(""));

context.lookup("") should always return no namespace because "" cannot
be bound in an XPath context.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Regier Avery J
2012-05-14 21:13:17 UTC
Permalink
Look at the whole context. It starts with making a context based on the contents of the document in question. Then I ask the context for an unbound namespace. This worked in previous versions of xom. It is quite handy to find an unbound namespace anywhere in the document. It is especially handy since in the context of my code the whole point is to setup a namespace context with which i need to robustly reference any namespace in the document, and the createnamespace() has just done the equivalent work of traversing the tree for namespaces. To do the same now I think I would have to iterate the document again searching for namespaces that have no prefix assigned. Maybe this is more correct anyways. In a large doc this will perform poorly. I would probably have to provide a heuristic to search only n levels deep or only the first child and risk missing some. It is frustrating because the knowledge is so close at hand but inaccessible behind this new line of code.

- Avery
Post by Elliotte Rusty Harold
On Mon, May 14, 2012 at 1:50 PM, Elliotte Rusty Harold
Post by Elliotte Rusty Harold
On Mon, May 14, 2012 at 1:44 PM, Regier Avery J
Post by Regier Avery J
It seems to be lost here that I am not attempting to bind to the null namespace. I am attempting to bind a prefix to a non-null namespace that currently has no prefix because the document did not specify it with one.
context.addNamespace("a", context.lookup(""));
context.lookup("") should always return no namespace because "" cannot
be bound in an XPath context.
--
Elliotte Rusty Harold
elharo at ibiblio.org
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
Regier Avery J
2012-05-14 21:26:35 UTC
Permalink
Or look at it this way: I have just had a default namespace context created for me and there is a big part of the namespaces list inaccessible via lookup(). A part that is typically the most important.

- Avery
Post by Regier Avery J
Look at the whole context. It starts with making a context based on the contents of the document in question. Then I ask the context for an unbound namespace. This worked in previous versions of xom. It is quite handy to find an unbound namespace anywhere in the document. It is especially handy since in the context of my code the whole point is to setup a namespace context with which i need to robustly reference any namespace in the document, and the createnamespace() has just done the equivalent work of traversing the tree for namespaces. To do the same now I think I would have to iterate the document again searching for namespaces that have no prefix assigned. Maybe this is more correct anyways. In a large doc this will perform poorly. I would probably have to provide a heuristic to search only n levels deep or only the first child and risk missing some. It is frustrating because the knowledge is so close at hand but inaccessible behind this new line of code.
- Avery
Post by Elliotte Rusty Harold
On Mon, May 14, 2012 at 1:50 PM, Elliotte Rusty Harold
Post by Elliotte Rusty Harold
On Mon, May 14, 2012 at 1:44 PM, Regier Avery J
Post by Regier Avery J
It seems to be lost here that I am not attempting to bind to the null namespace. I am attempting to bind a prefix to a non-null namespace that currently has no prefix because the document did not specify it with one.
context.addNamespace("a", context.lookup(""));
context.lookup("") should always return no namespace because "" cannot
be bound in an XPath context.
--
Elliotte Rusty Harold
elharo at ibiblio.org
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
Elliotte Rusty Harold
2012-05-15 04:12:33 UTC
Permalink
On Mon, May 14, 2012 at 2:26 PM, Regier Avery J
Or look at it this way: ?I have just had a default namespace context created for me and there is a big part of the namespaces list inaccessible via lookup(). A part that is typically the most important.
What prefix do you expect to be assigned to the default namespace?
Remember, the XPath spec is clear that no prefix is not an option
here. In an XPath expression the empty prefix always maps to no
namespace. When XOM violated this (unintentionally) it caused
noticeable bugs.

There's no traversal in either case, though. The context you created
was not based on the entire document and could not necessarily resolve
any namespace in the document. It was based on a single element.
--
Elliotte Rusty Harold
elharo at ibiblio.org
Loading...