Druckermann
Druckermann

Reputation: 741

Validating XML values via XSD with regex

I currently have XMLs of the following format:

<?xml version="1.0"?>
<trace_data>
  <pinfo>1</pinfo>
  <traces>
    <P0>21:39:09.776762 clock_gettime(CLOCK_BOOTTIME, {68, 27131557}) = 0
</P0>
    <P1>21:39:09.776831 epoll_ctl(4, EPOLL_CTL_DEL, 60, NULL) = 0
</P1>
    <P2>21:39:09.776856 close(60)               = 0
</P2>
  </traces>
</trace_data>

Where Process Elements (P0,P1, and so on) should form a sequence of up to n Processes (P0 ... Pn)

I'm now trying to create a XSD to validate these XMLs. Another important feature should be that the values of each of the processes should start with a time (e.g. 21:39:09.123123).

I came up with the following XSD, but can't figure out how to verify the values of the Process Elements.

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3schools.com"
xmlns="https://www.w3schools.com"
elementFormDefault="qualified">


<xs:element name="trace_data">
  <xs:complexType>
    <xs:element name = "pinfo" type="xs:string"/>
    <xs:element name = "traces" type="Process"/>
  </xs:complexType>
</xs:element>


<!-- <THIS DESCRIBES P0 to Pn FOR WINDOWSIZE n> -->
<xs:complexType name="Process">
        <xs:sequence>
            <xs:any minOccurs="1" maxOccurs="unbounded" processContents="lax"/>
        </xs:sequence>
    <xs:assert test=" "
</xs:complexType> 
<!-- <PROCESS ENDS HERE> -->


</xs:schema> 

Can anyone help me or point me in the right direction?

Thanks in advance.

Upvotes: 0

Views: 48

Answers (1)

Michael Kay
Michael Kay

Reputation: 163322

Whoever designed this XML format wasn't thinking in terms of what worked well in XSD, or for that matter, with any other XML tools. Use of structured element names like this feels like a smart idea, but is actually a thorough nuisance.

One approach would be to do your validation as a two-step process: first transform the XML to something more conventional (and more easily processed):

<traces>
    <P nr="0" time="21:39:09.776762">clock_gettime(CLOCK_BOOTTIME, {68, 27131557}) = 0</P>
    <P nr="1" time="21:39:09.776831">epoll_ctl(4, EPOLL_CTL_DEL, 60, NULL) = 0</P>
...
</traces>

and then apply an XSD to the result, which is now much more straightforward.

Though you'll still need XSD 1.1 assertions to validate that the numbers form a proper sequence:

<xsd:assert test="not(P[position() != @nr + 1])"/>

Upvotes: 1

Related Questions