You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2003/01/11 00:38:33 UTC

DO NOT REPLY [Bug 15983] New: - Union of Namespaces not working correctly

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15983>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15983

Union of Namespaces not working correctly

           Summary: Union of Namespaces not working correctly
           Product: XalanC
           Version: 1.4.x
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: XPathC
        AssignedTo: xalan-dev@xml.apache.org
        ReportedBy: berin@ozemail.com.au


Somewhere in the recent changes something has changed that 
has exposed a small bug with Namespaces and pointed out 
a second potential problem where namespace searches appear
to use nodes from parent elements even though the particular
namespace prefix has already been defined lower down in the
structure.

The small bug is that unions of Namespaces don't appear to
always work correctly :

z.xml :

----

<?xml version="1.0" encoding="UTF-8"?>
<foo:Root xmlns:bar="http://example.org/bar" xmlns:foo="http://example.org/foo">
  <bar:Something xmlns:bar="http://example.org/bar"
xmlns:foo="http://example.org/foo">
  </bar:Something>
</foo:Root>

----

Using XPathWrapper from Oct 21 interim release:

berin@zeus:bin$ ./XPathWrapper /tmp/z.xml
/foo:Root/bar:Something/namespace::bar[1]  "parent::node()/namespace::* |
self::node()"
the result set has 5 strings
item 1= "http://www.w3.org/XML/1998/namespace"
item 2= "http://example.org/bar"
item 3= "http://example.org/foo"
item 4= "http://example.org/bar"
item 5= "http://example.org/foo"

---

Using XPathWrapper from CVS (roughly 5 days old)

./XPathWrapper /tmp/z.xml /foo:Root/bar:Something/namespace::bar[1] 
"parent::node()/namespace::* | self::node()"
the result set has 6 strings
item 1= "http://example.org/bar"
item 2= "http://example.org/foo"
item 3= "http://www.w3.org/XML/1998/namespace"
item 4= "http://example.org/bar"
item 5= "http://example.org/foo"
item 6= "http://example.org/bar"

---

In the newer code, the union is not working correctly, 
and xmlns:bar is re-added to the node-set.

The findNamespace functions sets the subQueryResult as 
in document order, so the union function takes some
shortcuts, sees that the final node in the list is "lesser" than
the node being added so just adds it.  In fact, findNamespace
is not returning nodes in document order, so the shortcut
is incorrect.

Have attached a patch that fixed the problem on my system
by re-ordering the findNamespace loops to put the 
nodes in document order correctly.

---

The other problem is that I don't think (I could be
wrong?) that all these namespaces should be returned.

For example, the conext node expression I use above
returns two nodes, and it should return 1 (thus the
[1] expression to select the first found).

According to the XPath standard an element has 

"a namespace node:

- for every attribute on the element whose name starts
with xmlns:;

- for every attribute on an ancestor element whose name
starts with xmlns: _unless the element itself or a 
nearer ancestor redeclares the prefix_;

..."

(emphasis mine).

So for the expression:

/foo/bar/namespace::bart

only one node should ever be returned.

Not too sure what the best solution would be if my 
interpretation is correct.  Could :

- Search the subQueryResult list for an existing 
element that defines the same prefix (inneficient
for longer lists as the list is sorted in document
order not in namespace order, so there is no way
to shortcut in the search).

- Create a temporary list sorted in namespace prefix
order (with default at front) and then do a binary
search to see if the prefix is defined.

- Could use an existing namespace handling structure
to insert the namespaces and then pull back those
visible.  (Had a quick look and couldn't see anythign
that would map easily, but am not familiar enough with 
all the code.)