mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bernd Fondermann <bf_...@brainlounge.de>
Subject Re: [Vysper] XML Namespaces [WAS: Re: Moving new nbxml in trunk]
Date Mon, 10 May 2010 14:10:59 GMT
Niklas Gustavsson wrote:
> On Sun, May 9, 2010 at 9:52 PM, Bernd Fondermann <bf_jak@brainlounge.de> wrote:
>> This example is especially appropriate, as it includes beer:
> 
> We like that of course :-)
> 
>> <?xml version='1.0'?>
>> <Beers>
>>  <!-- the default namespace inside tables is that of HTML -->
>>  <table xmlns='http://www.w3.org/1999/xhtml'>
>>   <th><td>Name</td><td>Origin</td><td>Description</td></th>
>>   <tr>
>>     <!-- no default namespace inside table cells -->
>>     <td><brandName xmlns="">Huntsman</brandName></td>
>>     <td><origin xmlns="">Bath, UK</origin></td>
>>     <td>
>>       <details xmlns=""><class>Bitter</class><hop>Fuggles</hop>
>>         <pro>Wonderful hop, light alcohol, good summer beer</pro>
>>         <con>Fragile; excessive variance pub to pub</con>
>>         </details>
>>        </td>
>>      </tr>
>>    </table>
>>  </Beers>
>>
>> Now, I'd like to have an API like this:
>> builder.add("table", "http://www.w3.org/1999/xhtml").
>>    add("th").
>>    add("tf").
>>    addText("Name") ...
>>
>> and *not*
>> builder.add("table", "http://www.w3.org/1999/xhtml").
>>    add("th", "http://www.w3.org/1999/xhtml").
>>    add("tf", "http://www.w3.org/1999/xhtml").
>>    addText("Name") ...
>>
>> while you'd like it the other way round, right?
> 
> Yes (of course, you would likely use a constant rather than a string,
> but that's besides the point here).
> 
>> Reason for my position: This is straihtforward. You don't redefine java
>> variables when a new scope opens. You'd just redefine them to
>> shadow/override the outer scoped variable.
>> The inner XML elements are not arbitrary. Within a table, you'd expect
>> td, tr etc. to occur. No need to redefine the namespace.
>> However, if non-table elements occur, the namespace gets reset explicitly.
> 
> I'm not sure I follow along perfectly well here. But, I'll attempt to
> give an example of why I think inheriting the namespace in the XML
> creation step would be confusing. Let's take the following function
> that creates <item> elements in a MUC implementation:
> 
> private XMLElement createItem(XMLElementBuilder builder) {
>    builder.startInnerElement("item");
>    ...
> }
> 
> Now, in MUC, <item> elements can be contained both in the
> http://jabber.org/protocol/muc#user and
> http://jabber.org/protocol/muc#admin namespaces. Which one would this
> be in? To find out, I would have to backtrack to code to find out
> where the parent <x> element is created and see what namespace that is
> in. 

Well, if <item> has the same semantic in all cases, this would be perfect.
If it carries different semantics for both #user and #admin, you'd have
different signatures for the method anyway, to propagate these semantics.

> I would rather prefer the namespace be explicit.
> 
>> And I don't think you can get rid of looking up outer namespaces in any
>> serious implementation. In the second example, where every add() has an
>> explicit namespace declaration, one would
>> * either repeatedly render the declared xmlns on every element, no
>> tracking of outer ns needed
>> * or, not repeat rendering the declared xmlns, (like *all* XML examples
>> I've seen so far) which can only be achieved by keeping track of what
>> the current namespace is.
>>
>> I don't think XML like this:
>>  <table xmlns='http://www.w3.org/1999/xhtml'>
>>   <th xmlns='http://www.w3.org/1999/xhtml'>
>> <td xmlns='http://www.w3.org/1999/xhtml'>Name
>> ...
>> would be very compatible with XMPP clients. And would put much more
>> bytes on the wire than neccessary.
> 
> Oh, no one is saying this is the XML we should render, and nor do we
> currently. Instead, the renderer keeps a stack of the default
> namespaces and only outputs the xmlns attribute when needed. This is
> the same as the "renderers" (most APIs use the term "writer") does in
> the other previously mentioned APIs.

So basically, you're proposing to design an API which requires saying:
* I want to use ns 'http:123' on element 'iq'
* I still want to use ns 'http:123' on inner element 'query'
* I still want to use ns 'http:123' on inner element 'items'
* Yes, I still want to use ns 'http:123' on inner element 'item', really!

which is redundant. And you justify this by emphasizing that everybody
else does which is ok from an XML parser PoV, but not so much from a
Vysper PoV.

Why? Because the impact of implementing this would be:
* Changing a lot of working code, potentially introducing bugs, without
adding any information which isn't already there.
* Making stanza creation much more verbose, cluttering namespaces all
over the place.
* Tracking everywhere if a stream is c2s or s2s, to appropriately be
able to add xmlns='jabber:client' vs. xmlns='jabber:server'

I don't want to go through all this.

If the renderer/writer is intelligent enough to derive the ns, then
please let's follow "DRY", regardless of other APIs.

XMPP doesn't need a full blown XML parser. So I can see basically two
options:
1. Introduce (aka. keep) ways to make the renderer intelligent enough
(well, effectively make the API intelligent enough).
2. Rollback Vysper to it's own, buggy-but-sufficient XML handling code.

  Bernd

Mime
View raw message