|Subject:||Re: [stax_builders] [Axiom] XMLStreamWriter.writeNamespace problem|
|From:||Tatu Saloranta (cowt...@yahoo.com)|
|Date:||Apr 19, 2006 2:24:20 pm|
--- Eran Chinthaka <chin...@opensource.lk> wrote:
When we are using the XMLStreamWriter.writeNamespace, do we need to call the XMLStreamWriter.setPrefix method as well ?
I wish I had my earlier reply handy (in which I tried to summarize expected usage of all writeXxx() methods on writer side), but here is a reader's digest version of my understanding of the whole mess:
* "repairing" mode is "all-inclusive": writer takes care of all namespace bindings with whatever information it's passed (choosing what it'll use, wrt. prefixes), with absolute minimal help from the calling code. This adds some overhead, but is guaranteed to produce well-formed XML (wrt. namespace bindings). * "non-repairing" mode is minimum-effort: caller has to pass all relevant namespace information to the writer. The main idea is to minimize writer overhead. But there are multiple ways to pass information needed: prefix information is the prime example (can pass prefix arg to write methods, can call explicit setPrefix()).
* In repairing mode app should never try to write namespaces explicitly; it's writer's job. You need not call setPrefix(), but you can if you want to suggest a preferred prefix for a namespace URI. You can still use all forms of writeAttribute()/writeStartElement(), but implementation can choose whatever prefix mapping it wants, as long as output results in proper URI mapping for attr/element (b) In non-repairing mode, you have to write namespaces yourself, and the implementation only guarantees absolute minimum; it does not register any prefix/URI bindings for app to use. You do not have to call setPrefix(), unless you want to use the write methods that only take URI+localName; in this case implementation will use setPrefix() - set mappings.
So: calling setPrefix() is fully optional in all cases (in my opinion), with the sole exception of methods that only take nsURI+localName, in non-repairing mode (which is the default).
How I write this using the writer api is that, I first write all the namespace declarations of the Foo element. After that parser has writen y namespace as well. Then if I try to get the namespace for the prefix y, to write Bar element, the woodstox parser returns null.
Yes. In non-repairing mode it does not try to keep track of prefix/URI bindings app has used for write methods: this because its app's responsibility to handle namespace bindings (and keeping track of them would add overhead -- if that's desired, repairing mode makes more sense).
In your case you probably should just pass the prefix you used with namespace write to the element write? There is no benefit for setPrefix()/getPrefix() calls. This should work between implementations, as far as I know (stax ri, woodstox, Sun's sjsxp).
The whole setPrefix()/getPrefix() thing is one of the most confusing aspects of output (IMO). ;-/
But if I call the setPrefix method when writing the namespace in the Foo element, then this problem won't occur.
Yes. In this case you basically update a Map writer has for mapping URIs to prefixes, and can later on access that info (and writer itself too).
I checked StAX api to see the intended behaviour of the writeNamespace method to see whether we have to call setPrefix or not, but its silent about this.
Unfortunately that is the case. Specs is VERY sparse about details of the output side. My description above is based on my experiences tring to implement the thing, and although it's not an official statement, I have not heard of any objections to that interpretation.
IIRC, this is happening as expected in the StAX RI implemented by BEA.
What is the correct or accepted behavior ?
Hope this helps!
-+ Tatu +-
__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com