Peter B. West schrieb:
<SNIP ----- SNAP>
you're using namespaces.
setAttributeNS doesn't work for me following createElementNS. I get
org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or
change an object in a way which is incorrect with regard to namespaces.
This makes sense, but means that the only way to get the xmlns attribute
expressed is to normalizeDocument(). My feeling is that this reinforces
my point about the expected behaviour of the serializer.
Does it work for you? Maybe I'm doing something wrong.
Here a code snippet how this set attribute stuff works (at least for me :-) ),
also some explanations why the namespace stuff works that way in DOM.
As an example the following element:
- a Reference element that is part of some OASIS WSS namespace (not the same as
Reference in Signature)
- the element also contains an attribute in another WSS namespace
Example:
<wsse:Reference
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
wsu:Id="someIdentifier"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
...
</wsse:Reference>
Create the element first:
Element element = doc.createElementNS(WSConstants.WSSE_NS, "wsse:Reference");
this creates a namespace qualified element whose namespace is
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
(this is the value of the string constant "WSConstants.WSSE_NS").
Please note that wsse:Reference is the element's qualified name (Qname), which
may consist of "prefix:local name" or "local name" alone (refer to W3C namespace
specification).
Why using the namespace URI when creating the element? Refer to the following
sentences given in W3C's namespace spec:
<quote>
The Prefix provides the namespace prefix part of the qualified name, and MUST
be
associated with a namespace URI reference in a namespace declaration.
Note that the prefix functions only as a placeholder for a namespace name.
Applications SHOULD use the namespace name, not the prefix, in constructing
names whose scope extends beyond the containing document.
</quote>
This says: the prefix is a convenience (IMHO meant for "humans", not
necessarily for
computers :-) ). The real namespace is attached to the element.
Next step is to bind the prefix with a namespace using a namespace declaration:
element.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsse",
WSConstants.WSSE_NS);
The namespace declaration attribute:
- "WSConstants.XMLNS_NS" is the string "http://www.w3.org/XML/1998/namespace"
which
is fixed and MUST be given this way. This creates an namespace qualified
attribute
whose namespace is "http://www.w3.org/XML/1998/namespace".
- "xmlns:wsse" is the name of the attribute. Only the substring "xmlns:"
defines this
attribute as a namespace declaration
- the namespace URI of the element, for example
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
in case of Web Service Security extensions.
Now the namespace qualified attribute of the above element:
element.setAttributeNS(WSConstants.WSU_NS, wsu:Id", id);
element.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsu", WSConstants.WSU_NS);
Hope this helped a bit :-) .
Regards,
Werner
<my:name xmlns:my="a:b:c" xmlns:my="a:b:b"/>
I'm pretty sure that's because of your bug, using a DOM1 call to create that
initial attribute.
I'm not sure when this arrangement of the namespace and attribute occurs,
but the ordering may be affected by the order of creation -
createElementNS
first, followed by the attribute setup. In any case, I don't know what the
canonicalizer would do with this. Neither do I know which xmlns:my would
win
when the stream is read next time.
Neither will because that XML isn't well-formed. It won't parse.
Try using setAttributeNS and I think you'll have more luck.
-- Scott