XSD error: a-props-correct.2: Invalid value constraint value '0.00' in attribute

128 Views Asked by At

I am parsing following XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
  <xs:simpleType name="Money">
    <xs:restriction base="xs:decimal">
      <xs:pattern value="\d+\.\d{2}" /> 
      <xs:minInclusive value="0.00" /> 
      <xs:maxInclusive value="9999999.99" />
    </xs:restriction>
  </xs:simpleType>

 
  <xs:element name="Document" id="Document">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Issue" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute name="ChargeMinimum" use="optional" type="Money" default="0.00" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

I'm getting an error:

a-props-correct.2: Invalid value constraint value '0.00' in attribute 'ChargeMinimum'. cvc-pattern-valid: Value '0.0' is not facet-valid with respect to pattern '\\d+.\\d{2}' for type 'Money'.

2

There are 2 best solutions below

0
Martin Honnen On

What seems to happen here is that Xerces applies rule 2 from https://www.w3.org/TR/xmlschema-1/#coss-attribute which says:

2 if there is a {value constraint}, the canonical lexical representation of its value must be ·valid· with respect to the {type definition} as defined in String Valid (§3.14.4).

So value constraint is the default="0.00", the canonical lexical representation of the decimal 0.00 is (as far as I understand it) 0.0 and that value is failing validation against the pattern <xs:pattern value="\d+\.\d{2}" />.

So based on my current reading of the spec Xerces is giving an appropriate error message.

2
kjhughes On

I was able to reproduce using Xerces-J, and I concur with @MartinHonnen's assessment (+1).

As a work-around, consider using xs:fractionDigits instead of xs:pattern to limit the decimal places:

<xs:restriction base="xs:decimal">
  <xs:fractionDigits value="2"/>
  <xs:minInclusive value="0.00" /> 
  <xs:maxInclusive value="9999999.99" />
</xs:restriction>

Thanks to @MartinHonnen for pointing out a flaw in my previously suggested work-around.