[xsd-users] import, include, namespaces, restriction and schema
versioning
Eric Niebler
eric at boostpro.com
Mon Aug 31 12:45:07 EDT 2009
Boris Kolpackov wrote:
> Eric Niebler <eric at boostpro.com> writes:
>> Ideally, we would mark up the xsd and have CodeSynth fill in the
>> defaults for us, but that's something else entirely.
>
> Yes, it seems there are two general ways in which the user may want
> this to be handled:
>
> (1) Fill in the defaults for missing elements.
Yes.
> (2) Notify the user somehow about missing elements, presumably,
> during parsing.
I wasn't thinking of that. By "user" you mean me, the user of CodeSynth,
right? And by "notify" you mean invoke a registered callback. Huh, could
be useful, but is beyond my basic needs.
>>> On the surface validation during serialization often seem like a good
>>> idea. However, once you start thinking about what to do in case of
>>> an error, its usefulness becomes questionable, except, maybe, for
>>> debugging
>> I disagree, and this is where I see a situation where CodeSynth can
>> provide a value-add over plain mapping and validation. Imagine that we
>> have optional elements with special CodeSynth markup for what the value
>> the element should take when it's missing. If CodeSynth did a schema
>> validation pass on serialization, this is where the value for missing
>> elements could be filled in automatically.
>
> Wouldn't this be more naturally done during parsing so that the
> application developer doesn't have to worry about missing elements?
More naturally? Why? My intention is that the resulting XML produced by
our tools is always in the most up-to-date form and doesn't need to be
read back in in order to be patched up.
But the fix-up-on-write thought is beyond my basic needs. For my
scenario, what I'd like is:
1) On write, assert when a writeRequired element is missing.
2) On read, when a writeRequired element is missing, fill in a default
value.
>> That is, CodeSynth can proactively correct simple schema violations
>> with a little guidance from the xsd author.
>
> Such things can be implemented quite easily either during parsing
> or during serialization. And I agree, they can be useful. It is the
> full XML Schema validation that, IMO, is not very useful since it
> is not clear what to do when there is an error.
OK, understood.
>> If the issue is merely one of error detection and reporting, then yes I
>> agree that validation on serialization doesn't make much sense except
>> for debugging. But if you're willing to consider error correction, then
>> it does make sense.
>
> I think this will only work for automatic error correction, as above.
> In case the user intervention is required, it is not clear how to
> supply the error information (e.g., position, description, etc.) that
> can be usable for anything other than an error message.
Right. It's ok, I probably don't need this.
>>> Full-blown XSLT will also work and is probably simpler and quicker
>>> to implement (especially if you have multiple schema files connected
>>> via include/import). But the DOM approach is tidier since you don't
>>> need to carry two sets of schemas with your application.
>> Confused. If I use XSLT to process the schema, then I can still ship
>> only 1 set of schema, right?
>
> If you have a full-blown XSLT processor inside your application, then
> yes, you can ;-).
We may need it anyway.
>> So maybe xse:writeRequired isn't quite what I want. I'd like a way to
>> provide default values for optional elements in a way that they are
>> filled in automatically on read; and on write, either (a) fill them in
>> automatically, or (b) flag their absence as an error.
>
> If they are filled in on read, why do you also need this on write?
Because I wouldn't want my tool to produce XML that is missing
writeRequired elements. I may decide to publish the current schema
(minus CodeSynth extensions like xse:writeRequired or xse:refType) to
allow 3rd parties utilities to consume the XML my tool produces.
But asserting on the absence of a writeRequired elements achieves this
end just as well.
> Perhaps the application can create the object model and not provide
> new elements (because you generate default c-tors)? Is that the use
> case you had in mind?
No, see above.
>>> But I feel that it is only a part of the solution. The user of the
>>> mapping still has to detect the missing elements and provide some
>>> default values manually.
>> We're already doing that in our tool, so that's ok.
>
> That sounds like quite a tedious task. I wonder what API can we use
> to notify the application about missing elements and request the
> default values..? We could use DOM to return the default values
> but returning an object model instance would be more convenient.
> We could also pass the reference to the containing object model
> node in case the handler needs it.
I was hoping it could be as simple as something like this:
<xsd:compledType name="MyType">
...
</xsd:compledType>
<!-- default value for writeRequired MyType elements -->
<xsd:element name="MyTypeDefault" type="MyType">
...
</xsd:element>
<xsd:complexType> name="SomeOtherType">
<xsd:sequence>
<xsd:element name="foo"
type="MyType"
minOccurs="0"
xse:writeRequired="true"
xse:defaultValue="MyTypeDefault"/>
</xsd:sequence>
<xsd:complexType>
> One wild idea is to specify the handler function in the schema
> file, for example:
>
> <complexType name="person">
> <sequence>
> <element name="name" type="string"/>
> <element name="age" type="int" minOccurs="0"
> xse:defaultHandler="person_age_value"/>
> </sequence>
> </complexType>
>
> The signature of the person_age_value() function would be:
>
> int person_age_value (person& p);
>
> Then we can do something like:
>
> std::map<string, int> ages = ...
>
> int person_age_value (person& p)
> {
> return ages[p.name ()];
> }
>
> We would then have the companion attribute, xse:defaultValue, which
> is used to specify the default value in some form. Maybe an XPath to
> an element in the "default values file", for example:
>
> <complexType name="person">
> <sequence>
> <element name="name" type="string"/>
> <element name="age" type="int" minOccurs="0"
> xse:defaultValue="/values/person/age"/>
> </sequence>
> </complexType>
>
> The remaining question is how the values from this file are
> accessed to construct object model nodes. The cleanest approach
> would be to somehow embed these values directly into the generated
> code. Ideally, we would have a static object model instance that
> represents the default value. But it is not clear how to initialize
> it (Xerces-C++ is not usable during static initialization).
Whoa, you're going WAY beyond anything I had in mind. :-) Pretty cool,
but feels over-engineered for my purposes. Could it really be accomplished?
--
Eric Niebler
BoostPro Computing
http://www.boostpro.com
More information about the xsd-users
mailing list