The problem with XML Schema

Let’s just clear the air up front: I like XML Schema. It’s convient. It’s solves about 90% of all XML validation concerns. It’s concise.

I have been doing work lately that leverages the validation provided by XSD by supplimenting it with JavaScript and Java. The problem with XSD is that it’s not just simple XML. Sure, it’s written in XML, but that’s not the point. You can’t just rip through an XSD with XPath an extract out the information that you want. This becomes obvious when you think about the structure that XSD represents: there’s inheritance and references and all kinds of things that go “Bump” in the night. So the primary way that you can get at the guts behind what XSD is providing is via the Post-Schema-Validation Infoset (PSVI). But there’s a problem: it appears that there is no way to access non-native (i.e. non-xsd) attributes. It appears that if you have extended XSD in any way then there’s no way to access this information. Why allow it to be specified if one cannot access it?

Problem solved

I have been banging my head looking for a way to access non-native attributes of an XSD via PSVI. The problem I kept hitting was that the XSD API defines a seemingly limited XSAnnotation. There is only a annotationString method for retrieving the annotation. Taken literally (which is what I was doing) this will return the information within the <xsd:annotation> and that’s it.

I started looking for alternative techniques. I found some interesting information regarding XML Beans, SchemaAnnotation and non-native attributes. And this got me to thinking. I started to do some code splunking in Xerces and found that the member that backs getAnnotationString() looks like:

// the content of the annotation node, including all children, along
// with any non-schema attributes from its parent
private String fData = null;

Well that certainly does not match the PSVI description of “A text representation of the annotation”. The key is the “along with any non-schema attributes from its parent”. If your XSD looks like:

<xsd:element name="something" myNS:name="Something">

then getAnnotationString() will return:

<xsd:annotation myNS:name="Something" ... >

No, really.

Now those of you that are careful readers are likely sitting there wondering how this is even possible since it’s inconsistent. You’re wondering what happens when your XSD looks like:

<xsd:element name="something" myNS:name="Something">
<xsd:annotation myNS:name="Something else">

Well, I’m sure you’ve already guessed the answer:

<xsd:annotation myNS:name="Something else" ... >

Yup, the attribute from the <xsd:element> is “overwritten” and lost. And people wonder why I get bitter about these things. Always follow the rule of thumb: anytime that you do something “crafty” (such as updating the annotation to include the “annotations” (non-native attributes) from the parent element) you’re shooting yourself in the foot.

Why doesn’t XSObject have a XSObjectList getNonNativeAttributes() where the XSObjectList contains perhaps XSNonNativeAttribute objects, I don’t know. But that would have certainly saved me a few hours.

This is continued in More on XSD, PSVI and non-native attributes.



  1. Your post helped me a lot. I was looking at XSD API and wondering how could I access annotations, which belong to elements definitions. Google helped me to find your blog. Thanks!
    And happy new year! šŸ™‚

  2. I’m glad I could help. The funny thing is that I didn’t even remember writing this since it was a quick project. Thank goodness for this blog otherwise all of this info would be wasted somewhere in the back of my mind.
    Happy new year to you too!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s