Solved

Date Validation in XSD/XML test file

Posted on 2011-03-21
21
1,427 Views
Last Modified: 2013-12-13
I am using http://www.xmlvalidation.com/example.html?&L=0 to validate a sample XML file against an XML schema I am using. On validation of date (which I need to be in the format of 2010-12-31 or 2011-1-1) it throws an error. I am not sure if something is funky with the regexpression or the XSD.

XML portion:  <Policy Xml_PolicyID="0">
33                <PolicyNumber>ASD111</PolicyNumber>
34                <ExpirationDate>2012-01-31</ExpirationDate>
35                <Insured>
36                  <Name>ATT</Name>
37                  <PostalCode>12345</PostalCode>
38                  <County>BROWARD</County>
39                </Insured>
58              </Policy>

XSD portion:
<xs:complexType name="Policy">
    <xs:annotation>
      <xs:documentation>
        <xs:anyAttribute />
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="PolicyNumber" type="PolicyNumberType" />
      <xs:element minOccurs="1" maxOccurs="1" name="ExpirationDate" type="DateType" />
      <xs:element minOccurs="1" maxOccurs="1" name="Insured" type="Insured" />
    </xs:sequence>
    <xs:attribute name="CustomPolicyID" type="xs:string" use="optional" />
    <xs:attribute name="Xml_PolicyID" type="xs:nonNegativeInteger" use="required">
      <xs:annotation>
        <xs:documentation>Must be unique within the return</xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>

  <!-- PolicyNumberType -->
  <xs:simpleType name="PolicyNumberType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="50" />
      <xs:minLength value="1" />
    </xs:restriction>
  </xs:simpleType>

  <!-- Insured -->
  <xs:complexType name="Insured">
    <xs:annotation>
      <xs:documentation>
        <xs:anyAttribute />
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="Name" type="InsuredNameType" />
      <xs:element minOccurs="1" maxOccurs="1" name="PostalCode" type="PostalCodeType" />
      <xs:element minOccurs="1" maxOccurs="1" name="County" type="CountyType" />
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="InsuredNameType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="30" />
      <xs:minLength value="0" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="CountyType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="30" />
      <xs:minLength value="0" />
    </xs:restriction>
  </xs:simpleType>
 
  <xs:simpleType name="DateType">
    <xs:restriction base="xs:string">
      <xs:pattern value="^((((19|20)(([02468][048])|([13579][26]))-0?2-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0?[1-9])|(1[0-2]))-((0?[1-9])|(1\d)|(2[0-8])))|((((0?[13578])|(1[02]))-31)|(((0?[1,3-9])|(1[0-2]))-(29|30)))))$" />
    </xs:restriction>
  </xs:simpleType>


Error Received:

Errors in the XML document:
      34:      54      cvc-pattern-valid: Value '2012-01-31' is not facet-valid with respect to pattern '^((((19|20)(([02468][048])|([13579][26]))-0?2-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0?[1-9])|(1[0-2]))-((0?[1-9])|(1\d)|(2[0-8])))|((((0?[13578])|(1[02]))-31)|(((0?[1,3-9])|(1[0-2]))-(29|30)))))$' for type 'DateType'.
      34:      54      cvc-type.3.1.3: The value '2012-01-31' of element 'ExpirationDate' is not valid.
0
Comment
Question by:ramzafl
  • 9
  • 8
  • 4
21 Comments
 

Author Comment

by:ramzafl
Comment Utility
I was using:  http://regexlib.com/RESilverlight.aspx to validate the regular expression seen in the XSD. It seems to do what I want there...
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
If you only need the date to be of the form 2010-12-31 or 2011-1-1, why do you have all the crazy year checking? Can you clarify what the business rules are for valid dates?
0
 

Author Comment

by:ramzafl
Comment Utility
To allow for leap years. Etc. 2011-2-29 should not be accepted, but 2012-2-29 should be. Some months have 30 days, some 31, etc.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
So to confirm, you are trying not only to confirm structure, but you want to check validity of a date as well?
0
 

Author Comment

by:ramzafl
Comment Utility
Yes sir.
0
 

Author Comment

by:ramzafl
Comment Utility
I'd rather catch it during Schema Validation then in the backend...
0
 
LVL 74

Accepted Solution

by:
käµfm³d   👽 earned 250 total points
Comment Utility
Try this out and see if it works better:
^(?:19|20)(?:(?:(?:[02468][48]|[13579][26])-0?2-29)|\d\d-(?:(?:0?[469]|11)-(?:[012]?\d|30)|(?:0?[13578]|1[02])-(?:[012]?\d|3[01])|(?:0?2-(?:[01]?\d|2[0-8]))))$

Open in new window

0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
P.S.

If it won't compile, it might be because I used non-capturing groups. You can change it to this and it should work:
^(19|20)((([02468][48]|[13579][26])-0?2-29)|\d\d-((0?[469]|11)-([012]?\d|30)|(0?[13578]|1[02])-([012]?\d|3[01])|(0?2-([01]?\d|2[0-8]))))$

Open in new window

0
 

Author Closing Comment

by:ramzafl
Comment Utility
Works now, thanks.

Any chance you can explain to me how yours differs from mine (it seems to accept everything it should and nothing it should not from my initial set of tests?

Just interested in learning the how/why as well :-). Thanks.
0
 

Author Comment

by:ramzafl
Comment Utility
Actually I may have spoken too soon. It threw no errors in the XML validation but the XSD threw an error for invalid regexpression. I tried the second one you listed and got the same error on XML validation

Changed DateType to:
  <xs:simpleType name="DateType">
    <xs:restriction base="xs:string">
      <xs:pattern value=
                  "^(19|20)((([02468][48]|[13579][26])-0?2-29)|\d\d-((0?[469]|11)-([012]?\d|30)|(0?[13578]|1[02])-([012]?\d|3[01])|(0?2-([01]?\d|2[0-8]))))$"
                  />
    </xs:restriction>
  </xs:simpleType>

Still got:

"      34:      54      cvc-pattern-valid: Value '2012-01-31' is not facet-valid with respect to pattern '^(19|20)((([02468][48]|[13579][26])-0?2-29)|\d\d-((0?[469]|11)-([012]?\d|30)|(0?[13578]|1[02])-([012]?\d|3[01])|(0?2-([01]?\d|2[0-8]))))$' for type 'DateType'.
      34:      54      cvc-type.3.1.3: The value '2012-01-31' of element 'ExpirationDate' is not valid."
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
>>  Any chance you can explain to me how yours differs from mine

It's not that I mind, but yours was a bit difficult to interpret with all the parentheses! I decided to rewrite it solely because I could keep track of my parens as I worked it out. I can tell you that my intent was to design it as simplistic as I could and I made separate branches for the unique dates (e.g. leap year dates). The more specific parts of the pattern come at the beginning; the more generic parts come at the end.

I can describe specific parts of the pattern if you need/like.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
>>   It threw no errors in the XML validation but...

I'm looking into it.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
Take out the start-of-string ( ^ ) and end-of-string ( $ ) anchors:
(19|20)((([02468][48]|[13579][26])-0?2-29)|\d\d-((0?[469]|11)-([012]?\d|30)|(0?[13578]|1[02])-([012]?\d|3[01])|(0?2-([01]?\d|2[0-8]))))

Open in new window

0
 

Author Comment

by:ramzafl
Comment Utility
No dice...
"Errors in the XML document:
      34:      54      cvc-pattern-valid: Value '2012-01-31' is not facet-valid with respect to pattern '(19|20)((([02468][48]|[13579][26])-0?2-29)|\\d\\d-((0?[469]|11)-([012]?\\d|30)|(0?[13578]|1[02])-([012]?\\d|3[01])|(0?2-([01]?\\d|2[0-8]))))' for type 'DateType'.
      34:      54      cvc-type.3.1.3: The value '2012-01-31' of element 'ExpirationDate' is not valid."
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
Does the accepted solution actually work?
I doubt it,

Note that a pattern description in xsd schema's
- is always for the full pattern text string, never for a portion of it, so '^' at the start and '$' at the end are always implicit and should not be repeated.
- is very limited in syntax '(:?' is not supported for example

Your original pattern will work if you simply strip off the ^ and $ (tested and clear)

BUT!!!
Why going to all this trouble?
The lexical representation of your date is the same as the xs:date type
this is much and much more powerfull and it also takes leap years into account.
I strongly suggest that you change your DateType definition as such

    <xs:simpleType name="DateType" >
        <xs:restriction base="xs:date"/>
    </xs:simpleType>

A closing note: not that I am hungry for the points, but just to make sure that future visitors get the right solution...
if mine appears to be right and the accepted one wrong, please break the question open again, and close appropriatly,
otherwise you will send future readers on the wrong path
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
I see that kaufmed discovered the '^' and '$' issue in the mean time.

Weird, from the error messages, it seems you are validating with Xerces, and that is what I used for testing.
Your original pattern with '^' and '$' dropped works as it should in my Oxygen with Xerces-J
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
@Gertone

>>  A closing note: not that I am hungry for the points, but just to make sure that future visitors get the right solution...

I completely agree  = )
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
>>  as it should in my Oxygen with Xerces

Altova likes it too  : )
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
I see why you would use a pattern instead of xs:date,
you want to allow things like this
<ExpirationDate>2011-2-5</ExpirationDate>
and the xs:date literal value requires
<ExpirationDate>2011-02-05</ExpirationDate>
(I did not study the pattern in too much detail at first attempt)

I would personally throw in a normalisation filter prior to validation,
having an xs:date gives you all the power of typed calculation when you do schema aware processing,
it definitely can cut the code required after validation.


0
 

Author Comment

by:ramzafl
Comment Utility
Gertone: Thank you. I admit i jumped the gun and hit accepted solution a little early. My eyes deceived me.

I don't see how I can re-open this question back up, but Gertones solution of dropping the starting/ending ^/$ worked. Thank both of you for your assistance.
0
 
LVL 60

Expert Comment

by:Geert Bormans
Comment Utility
welcome,
please consider using xs:date by the way

about reopening:
you will need admininstrator assistance.
you can ask for assistance on this

note that kaufmed was first to suggest dropping the $ and ^, so he should get the accept
I just came in later explaining why that would be the solution
Basically try to reopen and then accept kaufmeds: ID:35182736
and to lead future readers to the actual explanation as well, you could put an assist on my ID:35182843
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Storage devices are generally used to save the data or sometime transfer the data from one computer system to another system. However, sometimes user accidentally erased their important data from the Storage devices. Users have to know how data reco…
A list of useful business intelligence software.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now