I've been on a very long hiatus from blogging. In fact I'd be surprised if anyone is even paying attention to this any more. I have a germ of an idea that I'm starting to believe is not half-bad, and I have to memorialize it somewhere. So even if I'm addressing a darkened, empty room, I have to at least voice this...
I've been doing a bit of web services in Java lately, and I've come to these conclusions:
- Object-to-XML (O/X) conversation layers stink. Only a subset of all complex and simple XML Schema node types can be accurately, unambiguously translated to object types in any popular OO language (C#, Java, C++, whatever). I'm not talking about parsing serialized XML to a DOM representation. I'm talking about generating an OOL type from a Schema type. For example, a Java class from an XML Schema complexType declaration.
- O/X conversion generates data-only classes. Classes generated from XML Schema have no specific behavior additions other than data accessors and validation. (Huh?) What I mean is that the generation of an OO class from the xsi:anyComplexType definition can do anything and everything an OO class generated from someURI:myComplexClass can do. There's no behavior in the specialized class. Why use an OO class at all? Just use DOM (or an equivalent) and save yourself a lot of unnecssary class generation.
Proposal
What about an OO language that uses the XML data model as the data model? It's crazy enough: it would actually work!
What I mean is, instead of generating a class that kind of approximates an XML complexType, you have a language in which someURI:myComplexType is a first class object type. To get an idea, check out this type which describe a person entity in the HR domain:
//
// someURI:Person complexType definition
//
namespace "someURI" as "ns";
import schema "http://www.w3.org/..." as "xsi";
public complexType Person
{
//...field attributes capture aspects not associated with behavior. Fields are either
// elements or attributes. The first element's type is xsi:string. There are
// three element fields and one attribute field in this ns:Person type. The
// first two elements have type xsi:string. The attribute has type ns:employeeID,
// a simple type ostensibly defined within the same namespace. The final
// element field has value type xsi:integer...
@public-read, @private-modify, @not-nill
element(xsi:string) first-name;
@public-read, @private-modify, @not-nill
element(xsi:string) last-name;
@public-read, @private-modify, @not-nill
attribute(ns:employeeID) id;
@public-read, @private-modify, @not-nill
element(xsi:decimal) salary;
// Programmatic contructor, takes 4 arguments. @public
Person(xsi:string a-first-name, xsi:string a-last-name, ns:employeeID a-id, xsi:decimal a-salary)
{ this/first-name = new element(xsi:string) {""};
this/first-name/value::. = a-first-name/value::.;
this/last-name = new element(xsi:string) {""};
this/last-name/value::. = a-last-name/value::.;
this/id = new attibute(ns:employeeID) {new ns:employeeID(0)};
this/id/value::. = a-id/value::.;
this/salary = new element(xsi:decimal) {0.0};
this/salary/value::. = a-salary/value::.;
}
// Example method in this class. @public
void give-raise(xsi:decimal percent)
{ //..."-:" below is an XPath shorthand for "value::."...
salary/value = salary/-: * (1.0 + percent);
}
}
Some features of this proposed language to point out:
- An complex type may have one or more fields. Each field is an element or an attribute. The value type of the field is also declared.
- XPath is used to traverse the object graph. For example, "this/first-name" is an XPath expression that resolves to the single "first-name" child element field of the node references by "this".
- The type-specific content of attributes and elements can be accessed using the synthetic XPath axis "value::", which only allows a single suffix character ".". That is, the type-specific value of a node is accessed using the XPath expression "theNodeRef/value::.". A shorthand version "-:" could be invented, which means "theNodeRef/value::. == theNodeRef/-:" is true.
- Code attributes are used to further shade the declaration of fields, classes, and methods. In the sample code above, each field has the code attributes "@public:read, @private:modify, @not-nill", which we assume a compiler and a runtime interpreter could understand.
11:29:26 AM
|
|