[Home] [By Thread] [By Date] [Recent Entries]

  • From: "Pete Cordell" <petexmldev@c...>
  • To: <xml-dev@l...>
  • Date: Tue, 19 Nov 2013 11:20:36 -0000

One of the problems with XML namespaces is not so much that the design was
bad, but the APIs (such as DOM) did a bad job of papering over the cracks.

I like Michael Kay's suggestion for namespaces by convention.  I think it
fits in well with Micro XML, which in many respects represents a clean sheet
for namespaces, and I thought it might be worth spending a little time
defining some suitable APIs so that the same problem doesn't happen again.

If we take the following snippet of XML:

   <com.example.person>
       <com.example.employer>
           <name>Megaco</name>
       </com.example.employer>
       <name>Fred Blogs</name>
   </com.example.person>

I would like to suggest an API that works something like this (I'm not a
Java programmer, but I'll try!):

   uDOM myDom = new uDOM();
   myDom.Read( "myxml.xml" );

   uDOMNode root = myDom.GetRoot();

   println( root.GetName() ); // prints "com.example.person"

Fairly standard up to that point, but now let's get more interesting and
move to the Node associated with "com.example.employer/name":

   uDOMNode employerName = myDom.FindNode( "com.example.employer:name" );

   println( employerName.GetName() ); // prints "com.example.person:name"
   println( employerName.GetLocalName() ); // prints "name"

This invokes Michael Kay's namespaces, but it's still hard work.  So let's
have the option to define out own namespace prefix mappings:

       myDom.SetNsMap( "emp", "com.example.employer" );

Now we can do:

   uDOMNode employerName = myDom.FindNode( "emp:name" );

   println( employerName.GetName() ); // prints "emp:name"
   println( employerName.GetLocalName() ); // prints "name"
   println( employerName.GetExpandedName() );
               // prints "com.example.employer:name"
   println( employerName.GetValue() ); // prints "Megaco"

Or to extract the name of a person:

   myDom.SetNsMap( "p", "com.example.person" );
   uDOMNode personName = myDom.FindNode( "p:name" );

   println( employerName.GetName() ); // prints "p:name"
   println( employerName.GetExpandedName() );
               // prints "com.example.person:name"
   println( employerName.GetValue() ); // prints "Fred Blogs"

We should also have something to handle the QName problem, for example:

   println( employerName.GetValueQName() );
               // prints "com.example.employer:Megaco"
   println( employerName.GetValueMappedQName() ); // prints "emp:Megaco"

To set a node's name each of the following would result in the same thing:

   personAge.SetName( "p:age" );
   personAge.SetName( "com.example.person:age" );
   personAge.SetName( "age" );

And similarly for QNames, each of the following would result in the same
thing:

   employerName.SetValueQName( "emp:Megaco" );
   employerName.SetValueQName( "com.example.employer:Megaco" );
   employerName.SetValueQName( "Megaco" );
               // Risky - adopts local context NS

What are your thoughts?

Pete Cordell
Codalogic Ltd
C++ tools for C++ programmers, http://codalogic.com
Read & write XML in C++, http://www.xml2cpp.com



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index]


Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member