'XML schema using int with pattern failing validation
I have an XSD schema with a nonNegativeInteger type that is restricted with a pattern (\d{2}) and try to validate an XML file, but get error 6937:
XML Validation: The canonical form of the value '01' is not valid according to the specified type. This can result from the use of pattern facets on non-string types or range restrictions or enumerations on floating-point types. Location: /*:xy[1]/*:Item1[1]/*:Field1[1]
CREATE XML SCHEMA COLLECTION dbo.XY_SCHEMA
AS'
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:simpleType name="Int_Abs_02">
<xs:restriction base="xs:nonNegativeInteger">
<xs:minInclusive value="01"/>
<xs:maxInclusive value="99"/>
<xs:pattern value="\d{2}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="Item1">
<xs:sequence>
<xs:element name="Field1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="Int_Abs_02"/>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="xy">
<xs:complexType>
<xs:sequence>
<xs:element name="Item1" type="Item1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>';
GO
DECLARE @xy XML(dbo.XY_SCHEMA)
SELECT @xy = '
<xy xsi:noNamespaceSchemaLocation="XY" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Item1>
<Field1>01</Field1>
</Item1>
</xy>'
I guess the canonical form is '1' which then is not using the given pattern?
I have read the MS documentation regarding Canonical Forms and Pattern Restrictions.
Is there any way I can make this work without changing the XML or XSD?
I'm using SQL Server 2014.
Solution 1:[1]
This is legal according to the XSD spec, but it makes life very difficult and is best avoided. If you want the value "01" to be valid, but "1" to be invalid, then in all probability the value you are dealing with is not really an integer at all, but a string made up of digits. (Compare phone numbers, where leading zeros are significant, and arithmetic is meaningless).
If it really is a number, for example a day of the month, then it's best to allow the leading zero to be omitted. If it isn't a number, but is some kind of code, then it's best to define it as a string that matches a regex.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Michael Kay |
