Matt,
Ok, lemme back up again and say this: everything you're saying is
correct. But...
a. There are lots of people, lotsa places that are duplicating this
problem. I've even seen tutorials that demonstrate this way of
"declaring" the namespace!
b. Code that uses this technique is already been using in production
environments. The XML Security Suite is one example.
c. Despite the fact that this is a problem with the way the API is used,
people use it and their code still works. If they take that same code and
use it with Apache SOAP, it stops working because Apache SOAP takes a
strict approach. If it works outside of SOAP, but not in SOAP, then
people will assume (rightly or wrongly) that there is a bug in Apache
SOAP.
d. I highly doubt we're going to be able to convince people they need to
rewrite their code just so they can use Apache SOAP.
e. The change I'm proposing is small and simple enough that it will have
very little impact on the rest of the serialization code so there is
really no harm done by committing them.
f. We can go back and forth all day about how the use of the DOM API's is
incorrect but it still doesn't solve the problem since the use of the DOM
API's is completely out of my control.
h. In some cases, practicality should win over strict adherance to the
rules. I think this should be one of those cases.
- James Snell
Software Engineer, Internet Emerging Technologies, IBM
James M Snell/Fresno/IBM - [EMAIL PROTECTED]
These things I have spoken to you, so that in Me you may have peace.
In the world you have tribulation, but take courage; I have overcome the
world.
- John 16:33
Please respond to [EMAIL PROTECTED]
To: [EMAIL PROTECTED], James M Snell/Fresno/IBM@IBMUS
cc: "Sanjiva Weerawarana" <[EMAIL PROTECTED]>, Sam Ruby/Raleigh/IBM@IBMUS
Subject: Re: Bug with DOM2Writer
Hi James,
I agree with Sanjiva. The problem is the way you are using the DOM APIs.
To create a qualified element, the method is:
public Element createElementNS(java.lang.String namespaceURI,
java.lang.String qualifiedName) throws DOMException
Note that the second argument is called "qualifiedName". So, you would
write:
Element test = doc.createElementNS("testing", "s:test");
not:
> Element test = doc.createElementNS("testing", "test");
> test.setPrefix("s");
> test.setAttribute("xmlns:s", "testing");
> Why am I adding the test.setAttribute("xmlns:s", "testing")? Because
> that's about the only ways to declare namespaces in the DOM API. I
could
You can declare them implicitly by using them. Search through the JavaDocs
for org.w3c.dom.Element and org.w3c.dom.Document, looking for "xmlns", and
they say a bit more about this.
> I could get around this problem by simply removing the
> test.setAttribute("xmlns:s", "testing") line, but unfortunately, I don't
> have access to the code that creates the real DOM document I'm trying to
> work with (the above is just an example). So the setAttribute line
> remains and we have to work around the problem within the DOM2Writer.
I believe the bug is in the code which is calling test.setAttribute
("xmlns:s", "testing"). Not to mention that qualified attributes are
supposed to be created by calling Element.setAttributeNS(...), not
Element.setAttribute(...). If you don't use the correct factory methods,
you are creating Nodes which appear qualified, but are in fact not (at
least as far as the DOM representation is concerned).
If you use the correct method call to set the qualified attribute,
DOM2Writer will interpret this as a namespace declaration, and do the
right
thing. That is, you should be using:
test.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:s", "testing");
To set the namespace declaration.
Thanks,
-Matt
"Sanjiva
Weerawarana" To: <[EMAIL PROTECTED]>,
Matthew Duftler/Watson/IBM@IBMUS, Sam
<sanjiva@watso Ruby/Raleigh/IBM@IBMUS
n.ibm.com> cc:
Subject: Re: Bug with
DOM2Writer
09/28/2001
02:33 AM
This is not a bug. So please do not commit this change!
The problem is that you're using the DOM APIs incorrectly.
If you start creating attributes that look like qualified names,
then you'll confuse the writer (and lots of other things). If you
want to create a namespaced attribute, then there's a right way
to do it - you are doing it the wrong way. The key point is
that xmlns:s is *not* an attribute of the {testing}test element.
Sanjiva.
----- Original Message -----
From: "James M Snell" <[EMAIL PROTECTED]>
To: "Matthew Duftler" <[EMAIL PROTECTED]>; "Sam Ruby" <[EMAIL PROTECTED]>;
<[EMAIL PROTECTED]>
Sent: Friday, September 28, 2001 2:53 AM
Subject: Bug with DOM2Writer
> Package: org.apache.soap.util.xml.DOM2Writer
>
> Problem: In some cases, the DOM2Writer will output duplicate XML
namespace
> declarations on a single element, thereby making the XML output invalid.
>
> Example, let's say I want to create the following XML output:
>
> <s:test xmlns:s="testing>
> <hello />
> </s:test>
>
> To do so, I use the following code.
>
> Document doc = ... create document
> Element test = doc.createElementNS("testing", "test");
> test.setPrefix("s");
> test.setAttribute("xmlns:s", "testing");
> Element hello = doc.createElementNS("testing", "hello");
> test.appendChild(hello);
> doc.appendChild(test);
>
> Run this through the DOM2Writer, and the output is:
>
> <s:test xmlns:s="testing" xmlns:s="testing">
> <hello />
> </s:test>
>
> Notice the duplicate xmlns:s declarations.
>
> This is caused by the fact that the xmlns:s declaration is set as an
> attribute on the element. DOM2Writer checks to see if the element
> namespace and prefix have been declared before serializing all of the
> attributes. In this case, if the "s" prefix for the "testing" namespace
> has not been declared, the xmlns:s="testing" is added to the XML output.
> Then, however, the attributes are looped through and serialized, causing
a
> duplicate declaration to be printed.
>
> Why am I adding the test.setAttribute("xmlns:s", "testing")? Because
> that's about the only ways to declare namespaces in the DOM API. I
could
> get around this problem by simply removing the
> test.setAttribute("xmlns:s", "testing") line, but unfortunately, I don't
> have access to the code that creates the real DOM document I'm trying to
> work with (the above is just an example). So the setAttribute line
> remains and we have to work around the problem within the DOM2Writer.
>
> Proposed Solution:
>
> When looping through the attributes, check to see if the attribute is an
> XML namespace declaration, and if so, whether or not the namespace has
> already been declared. If so, skip it and move on.
>
> The proposed modified DOM2Writer is attached. Can somebody please
review
> to make sure that my head is screwed on straight and I didn't overlook
> something before I commit it.
>
>
>
> - James Snell
> Software Engineer, Internet Emerging Technologies, IBM
> James M Snell/Fresno/IBM - [EMAIL PROTECTED]
> These things I have spoken to you, so that in Me you may have peace.
> In the world you have tribulation, but take courage; I have overcome the
> world.
> - John 16:33