[relaxng-user] Java datatype library:
value object->string conversion
Julian Scheid
julian at sektor37.de
Thu Nov 4 16:34:52 ICT 2004
Kohsuke Kawaguchi wrote:
> Oh, OK. But if you are doing this, can't you just remember what literal
> you passed in to Datatype.createValue, along with the context that you
> passed in? You can also use .getClass() to find out what the type of
> the value is for that particular literal.
Many thanks for your suggestions, but unfortunately this doesn't solve
my problem. Please allow me to outline my situation briefly.
I have a piece of software which reads a grammar and generates a parser
class and a set of value classes reflecting this grammar.
Suppose I feed a grammar to the system and this grammar contains the
following fragment:
<element name="address">
...
<element name="zipcode">
<data type="zipcode" datatypeLibrary="http://foo/mydatalib"/>
</element>
</element>
Given this grammar, my system ought to generate a value class like the
one below (scoping, getters and setters omitted, boxing issues ignored):
class Address
{
...
Integer zipcode;
}
Let's call this "generation time"; at this time my system only deals
with a grammar document - as opposed to runtime, when the generated code
deals with a data document.
In above example I assume that the "zipcode" Datatype's createValue()
method returns objects of type Integer. But how can my system possibly
know the type *at generation time*?
In order to use getClass() it would have to call createValue() first,
but what literal should it pass in? The createValue() implementation
will likely only return an Integer if a valid zip code literal is being
passed in, and fail otherwise. But my system doesn't have a sample zip
code at this point in time, since it doesn't operate on a data document
at generation time. All information it has at this point comes from the
grammar, and that doesn't include a sample literal.
This is why a getValueType() method would be very helpful in terms of
code generation, at least for my approach to data binding.
>
>> I agree that when it comes to transforming to literals the issue is
>> somewhat more complex than I indicated. But isn't what's needed
>> basically a registerNamespace(String uri, String prefix) method in the
>> context?
>
>
> No. My point was that generating code like the following is a lot more
> work:
>
> public static final QName ABC = new QName("foo","bar");
>
> It's clearly not just an issue of declaring a new namespace.
Let me try to approach the problem from a different angle and briefly
recollect my understanding of QNames. Please correct me if I'm mistaken.
A QName is a local name together with a namespace, where the namespace
is identified by a URI.
So a QName could be { foo, http://bar/baz }.
In the following code, both "qname" attributes resolve to this
particular QName, correct?
<fubar qname="a:foo" xmlns:a="http://bar/baz"/>
<fubar qname="b:foo" xmlns:b="http://bar/baz"/>
When a QName is being read, the Datatype implementation can use the
ValidationContext to resolve the prefix, yielding the URI. It would then
store both the local name and the URI in some value object which
represents the QName semantically. (So the prefix is only a syntactic
construct and doesn't contribute to a QName semantically.)
Later, when the QName is about to be converted "back" to a literal, the
following is necessary in order to preserve the QName semantically:
- a prefix needs to be chosen that doesn't conflict with another prefix.
- the prefix needs to be bound to the URI "near" or "above" the literal
in the output document.
In addition, in terms of readability or "prettiness" of the output document
- the same prefix should be used for the same URI all over the document
- the prefix shouldn't be chosen arbitrarily but rather according to
user preference, or in a way that a prefix that was used in an input
document is preserved.
Couldn't all of this be achieved rather easily by a method in the
context object which, given a namespace URI, returns a prefix for this
URI and remembers the binding so that the code which writes the XML
document can output the binding appropriately?
This new context method could use an approach for determining the prefix
roughly like this:
- lookup the prefix in some registry which has been initialized either
by the user and/or by the system (if the data model hasn't been
constructed from scratch but rather has been read from an XML document
earlier)
- reuse a binding, if a prefix has already been chosen for the namespace
earlier in the output process
- use a generic prefix if all else fails (like a:, b:, c: ...), possibly
emitting a warning message.
I may be completely off track, but to me it looks like all that's needed
to solve the QName issue is this additional context method complementing
resolveNamespacePrefix(). It seems to me that the facility required for
output is essentially the inverse of the namespace resolution facility
used for input.
Am I missing something here?
Thanks for your consideration,
Julian
More information about the relaxng-user
mailing list