Is there some sensible way to have elements with strongly-typed simple-types and also attributes?
Okay, I have an XSD schema which has a million (er, hundred) elements that might look like this:
<xsd:element name="DocumentDescription" type="xsd:string" />
<xsd:element name="DocumentDateTime" type="xsd:dateTime" />
<xsd:element name="DocumentSize" type="xsd:int" />
That's dandy. However, I really want all of these elements to also have some common attributes on them like, let's say, "format" and "isVisible". i.e. have a schema like:
<DocumentDescription isVisible="true">doc description</DocumentDescription>
<DocumentDateTime format="dd/mm/yyyy" isVisible="true">1/1/2008</DocumentDescription>
<DocumentSize format="0.00 KB" isVisible="false">5403</DocumentSize>
I could do it manually, and horribly, by adding all such attributes to the XSD when I generate it, something like this:
<xsd:element name="DocumentDescription" />
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="format" type="xsd:string" />
<xsd:attribute name="isVisible" type="xsd:boolean" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:element name="DocumentDateTime" />
... etc
...but in an ideal world I'd rather define it as a complexType:
<xsd:complexType name="customType">
<xsd:complexContent>
<xsd:extension base="???">
<xsd:attribute name="format" type="xsd:string" />
<xsd:attribute name="isVisible" type="xsd:boolean" />
...which means I could just do:
<xsd:element name="DocumentDescription" type="customType" baseType="xsd:string" />
<xsd:element name="DocumentDateTime" type="customType" baseType="xsd:dateTime" />
<xsd:element name="DocumentSize" type="customType" baseType="xsd:int" />
The problem with my "ideal world" code is that:
a) I've no valid <xsd:extension base-"???"
>, since really I don't care what I'm extending; I want to extend all types. Seems like the "xsd:anyType" is appropriate, yet then the element becomes a weakly typed container does it not?
b) I can no longer specify the simple type on the <xsd:element
>, since now the type is the complex "customType" I defined. Hence the imaginary "baseType" attribute I put there...
So can I add attributes to simple types in a non-clunky way? Or do I need to define a dozen complexTypes that are all identical except for the simple type that they extend?
Strongly-typed elements not only describe the data more sensibly, but when I use them for XML mapping in Excel (and this is the whole purpose behind these things), the strong-typing means that Excel sets the cell formatting correctly based on the type.
I'm probably looking at it all the wrong way! Any advice appreciated.
The minOccurs attribute specifies the minimum number of times that the element can occur. It can have a value of 0 or any positive integer. The maxOccurs attribute specifies the maximum number of times that the element can occur.
XSD elements can be of type simpleType , complexType , or anyType . An element of type simpleType contains only text. It cannot have attributes and elements. An element of type complexType can contain text, elements, and attributes.
elementFormDefault="qualified" is used to control the usage of namespaces in XML instance documents (. xml file), rather than namespaces in the schema document itself (. xsd file). By specifying elementFormDefault="qualified" we enforce namespace declaration to be used in documents validated with this schema.
It's not entirely clear which aspect of the manual solution you regard as horrible; if it's the idea of having to define n different types just because they will need to extend n different base types, then you're stuck.
If it's the idea of having to have n different declarations for the format
and isVisible
attributes, then you might find it less horrible to use a named attribute group to hold those definitions:
<xs:attributeGroup name="globals">
<xs:attribute name="format" type="xs:string"/>
<xs:attribute name="isVisible" type="xs:boolean"/>
</xs:attributeGroup>
The declarations of the various complex types you need remain repetitive but are now slightly less verbose:
<xs:complexType name="string">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attributeGroup ref="my:globals"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="dateTime">
<xs:simpleContent>
<xs:extension base="xs:dateTime">
<xs:attributeGroup ref="my:globals"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="int">
<xs:simpleContent>
<xs:extension base="xs:int">
<xs:attributeGroup ref="my:globals"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
And the declarations of your elements are now slightly simpler than in your 'ideal' case:
<xs:element name="DocumentDescription" type="my:string" />
<xs:element name="DocumentDateTime" type="my:dateTime" />
<xs:element name="DocumentSize" type="my:int" />
[quote]could do it manually, and horribly, by adding all such attributes to the XSD when I generate it, something like this:[/quote]
I'm afraid this is your only "proper", XSD-schema compatible way to do it.
XSD can be convoluted to author at times - but it helps keeping things safe :-)
Marc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With