XML Schema pattern which allows no data at all - xsd

I'm receiving xml data in these two forms from an external company
<currencydate>20110910</currencydate>
<currencydate/>
I want to verify using a pattern that this date indeed has the format YYYYMMDD like this
<xs:element name="currencydate" type="dateType"/>
<xs:simpleType name="dateType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-2][0-9]{3}[0-1][0-9][0-3][0-9]"/>
</xs:restriction>
</xs:simpleType>
This works fine. But the validation breaks on the empty element
So I added the minOccurs like this
<xs:element name="currencydate" type="dateType" minOccurs="0"/>
No success so I added nillable
<xs:element name="currencydate" nillable="true" type="dateType" minOccurs="0"/>
No success, I guess the element is there so it checks the pattern. So I changed the pattern
<xs:pattern value="[0-2][0-9]{3}[0-1][0-9][0-3][0-9]|"/>
I only added the pipe indicating the value can be empty. But still no success.
So my question is: how can I check the data pattern but also allow the value
<currencydate/>
Please note I'm receiving this data from an external company which does not provide an xsd nor are they willing to change anything for me.

Did you already try
<xs:pattern value="|([0-2][0-9]{3}[0-1][0-9][0-3][0-9])" />
as suggested in how to validate empty string value tag in xsd?
I only tried it in VS 2010 Express but it seems to work even if a comment in the linked post tells otherwise.

Related

Handling a leading zero in a wsdl

I got provided an XSD that had a type representation as follows:
<xs:element name="PhoneNumber">
<xs:simpleType>
<xs:restriction base="xs:nonNegativeInteger">
<xs:pattern value="04[0-9]{8}"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Now when we use Apache CXF to convert this from the XSD to autogenerated code which assigns it as a BigInteger.
So what I would like to know:
Is that piece of XSD valid? (I tend to think not as an Integer will never exist with a leading zero)
Is there anyway to get Apache CXF to handle such a condition and force the type to be a string?

how to provide unit values with mininclusive and maxinclusive values

I have one DTD
<parameter name="ReferenceSignalPower" access="readWrite">
<syntax>
<int>
<range minInclusive="-60" maxInclusive="50" />
<units value="dBm">
</units>
</int>
</syntax>
</parameter>
I am new to XML schema i am not aware how to provide unit values with this XML schema
<xs:element name="ReferenceSignalPower">
<xs:simpleType>
<xs:restriction base="xs:unsignedInt">
<xs:minInclusive value="-60"/>
<xs:maxInclusive value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
XML schemas do not have a concept of measurement units, you can define an XML attribute or XML element to contain numbers with certain restrictions (or other standard data-types like dates etc.), but it is the responsability of the application that reads the XML to interpret such numbers as values in a specific unit of measure.
If you want to add measurement unit information in the schema you can do it using the appInfo element - e.g.:
<xs:element name="ReferenceSignalPower">
<xs:simpleType>
<xs:annotation>
<xs:appinfo>
<units value="dBm"/>
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:int">
<xs:minInclusive value="-60"/>
<xs:maxInclusive value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
but then you'll have to parse and interpret this information yourself.
You don't say what your question is, but I suppose the question is "why does this not work?"
Your declaration is almost right, but not quite. Why are you using unsignedInt as your base type, when you want a minimum value of -60? The minimum value of unsignedInt is already set to zero.
The XSD spec assumes that if you attempt to set a minimum value to a value that's not part of the value space of your type, then there is an error somewhere.
So: either use a signed integer type as your base type, or set the minimum value to a value that is actually present in the base type.

XSD: restrict attribute to xs:float or ""

I'm trying to define an element type in XSD, for which i want an optional attribute, which if present can either contain a float, or be empty (but still present).
i.e:
<xs:element name="MyElement">
<xs:complexType>
<xs:attribute name="optionalFloatAttribute" type="xs:float" use="optional"/>
</xs:complexType>
</xs:element>
Needs "fixing" to allow all of the following xml:-
<MyElement/>
or
<MyElement optionalFloatAttribute=""/>
or
<MyElement optionalFloatAttribute="3.14159"/>
The only way I can see of doing this is to change type to xs:string, and use xs:restriction with a regular expression. But this doesn't seem very ideal to me. Is there a better way?
And I have to be able to support these variations of the xml - the program and existing xml is legacy, and I am trying to back-create a schema to match the myriad variations I see in what we have to regard as valid xml.
You can define custom type for that by combining float and empty string:
<xs:element name="MyElement">
<xs:complexType>
<xs:attribute name="optionalFloatAttribute" type="emptyFloat" use="optional"/>
</xs:complexType>
</xs:element>
<xs:simpleType name="emptyFloat">
<xs:union>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:length value="0"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType>
<xs:restriction base='xs:float'>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
Or using regExp:
<xs:simpleType name="emptyFloat">
<xs:restriction base="xs:string">
<xs:pattern value="-?\d*\.?\d*"/>
</xs:restriction>
</xs:simpleType>
If you could stand using an element rather than an attribute you could make the xs:float nillable. This way you can use the xsi:nil="true" in your instance document to indicate that the element has no value:
<!-- definition -->
<xs:element name="quantity" type="xs:float" nillable="true" />
<!-- instance -->
<quantity xsi:nil="true" />
No equivalent for attributes though.
I don't think there's a way to handle this and use xs:float. Fundamentally it comes down to the fact that empty string isn't a valid number. You'd either normally expect a value of 0, or for the element to be missing altogether. There's a good explanation as the answer to the following question:
Empty elements for primitve datatypes forbidden in XSD
It seems that the option of using xs:string and a regexp might be your best plan.

How to define a Constant in XSD

Is there a way to define a constant value and use that constant in the preceeding XSD? I have a common value I want to use for various xs:element tag's maxOccurs attributes. Like constants in other languages, I want to make the change in one place should the value backing MyConst were to ever change.
<!-- Can I do this? -->
<ConstantValue id="MyConst" value="10"/>
...
<xs:element name="sandwich_meat" type="xs:string" minOccurs="0" maxOccurs="MyConst"/>
<xs:element name="sandwich_name" type="xs:string" minOccurs="0" maxOccurs="MyConst"/>
You can try to define a simpleType with a restriction:
<xs:simpleType name="AConstantHere">
<xs:restriction base="xs:string">
<xs:enumeration value="CONSTANT_VALUE_HERE"/>
</xs:restriction>
</xs:simpleType>
It allows only one value.
No it is not allowed that way. However you can define your own type with a fixed value in it somewhere on top of your XSD (place dosen matters) and use that type for the elements.
It's not possible with plain schema, but maybe XML entities will do the trick?

How to declare a non-string element as having optional content in XML Schema

I have seen XML Schema element with attributes containing only text but I have an element that's an xs:dateTime instead.
The document I'm trying to write a schema for looks like this:
<web-campaigns>
<web-campaign>
<id>1231</id>
<start-at nil="true"/>
</web-campaign>
<web-campaign>
<id>1232</id>
<start-at>2009-08-08T09:00:00Z</start-at>
</web-campaign>
</web-campaigns>
Sometimes the xs:dateTime element has content, sometimes it doesn't.
What I have so far (which doesn't validate yet) is:
<xs:element name="start-at">
<xs:complexType mixed="true">
<xs:simpleContent>
<xs:extension base="xs:dateTime">
<xs:attribute name="nil" default="false" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
If I replace xs:dateTime with xs:string, I can validate the document just fine, but I really want an xs:dateTime, to indicate to consumers what's in that element. I tried with/without mixed="true" as well, to no avail.
If it makes a difference, I validate using xmllint (on Mac OS X 10.5) and XML Schema Validator
you can define your own types as union of types.
1/ define the "empty" type as a string that only allows "" ähm nothing :)
<xs:simpleType name="empty">
<xs:restriction base="xs:string">
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
2/ next define a type that allows date AND empty
<xs:simpleType name="empty-dateTime">
<xs:union memberTypes="xs:dateTime empty"/>
</xs:simpleType>
3/ declare all your nullable datetime elements as type="empty-dateTime"
You need
<xs:element name="start-at" minOccurs="0">
mixed-mode isn't relevant to your situation, you don't need that. By default, minOccurs="1", i.e. the element is mandatory.
With minOccurs="0", you either specify the element with content, or not at all. If you want to be able to permit <start-at/>, then you cannot use xs:dateTime.

Resources