I have been given a schema, instances of which I'm required to be able to
consume and generate. I'd like to be able to manipulate these instances as
DataSets internally in my application. The schema defines the following
simpleType:
<xs:simpleType name="cs">
<xs:restriction base="xs:token">
<xs:pattern value="[^\s]*"/>
</xs:restriction>
</xs:simpleType>
If I'm reading that correctly, it's not that different from a normal
xs:token - it simply imposes the extra restriction that the token contain no
whitespace whatsoever. (The normal xs:token permits single internal white
spaces.)
This works if I use it as the type of an element like so:
<xs:element name="BrokenDataSet" msdata:IsDataSet="true">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="cs"/>
</xs:sequence>
</xs:complexType>
</xs:element>
The DataSet generator is quite happy to deal with this. However, this 'cs'
type is often used in a less direct way. For example, it is often used
either directly, or through derivation (xs:restriction) as an attribute in a
complex type. This causes an error (whether using it as a derived type or
using it directly.) For example this:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="BrokenDataSet"
targetNamespace="http://tempuri.org/BrokenDataSet.xsd"
elementFormDefault="qualified"
attributeFormDefault="qualified"
xmlns="http://tempuri.org/BrokenDataSet.xsd"
xmlns:mstns="http://tempuri.org/BrokenDataSet.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:simpleType name="cs">
<xs:restriction base="xs:token">
<xs:pattern value="[^\s]*"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="bar">
<xs:attribute name="spong" type="cs"/>
</xs:complexType>
<xs:element name="BrokenDataSet" msdata:IsDataSet="true">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="bar"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
results in the following from XSD.EXE:
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 1.1.4322.573]
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
Error: There was an error processing 'BrokenDataSet.xsd'.
- Undefined data type: 'token'.
The error message suggests that something has gone wrong somewhere with
namespaces - 'token' is a standard XSD type, so the fact that XSD.EXE is
barfing on it would typically be indicative of something being wrong
somewhere with the use of namespace declarations. This is why I've included
the entire file above - I'm pretty sure it's all correct. (And XML Spy is
happy with it - it's just XSD.EXE /dataset that doesn't like it.)
Interestingly, if I change from xs:token to xs:string as the base type:
<xs:simpleType name="cs">
<xs:restriction base="xs:string">
<xs:pattern value="[^\s]*"/>
</xs:restriction>
</xs:simpleType>
the error goes away. So it looks like this is specifically something to do
with 'token'. (Rather than being a namespace problem as you might initially
guess from the error message.)
Unfortunately, changing the definition of this 'cs' simpletype to the above
doesn't work in another case that crops up frequently. The schema I have to
work with frequently derives new simpleTypes from the 'cs' type above. For
example, here's a simplified example. (The real thing has more enumeration
items, but this simple version illustrates the problem.)
<xs:simpleType name="cs_NullFlavor">
<xs:restriction base="cs">
<xs:enumeration value="NI" />
<xs:enumeration value="NINF" />
</xs:restriction>
</xs:simpleType>
If we use this as an attribute type by changing the definition of 'bar' in
the earlier example:
<xs:complexType name="bar">
<xs:attribute name="spong" type="cs_NullFlavor"/>
</xs:complexType>
I now get this error out of XSD.EXE:
Error: There was an error processing 'BrokenDataSet.xsd'.
- Undefined data type: 'cs'.
when I try to use the 'bar' type. (Note that this is using the modified
version of 'cs' above - the one which does work if it is used directly as a
attribute type. This 'fixed' version turns out to be broken in derivation
scenarios like this.)
Changing every simple type that derives from 'cs' and making it derive
directly from 'xs:string' instead gets rid of the errors, but requires
non-trivial changes of the content (and meaning) of the schemas. This is
undesirable since I don't own the schemas - it means I'm now working with a
schema definition that is different from my client's. That's risky, and also
a pain when they come up with new or updated schemas.
Is there a better way to work around this problem?
--
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
DevelopMentor - http://www.develop.com/