[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
MicroXML APIs and MK Namespaces by Convention
- From: "Pete Cordell" <petexmldev@codalogic.com>
- To: <xml-dev@lists.xml.org>
- 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]