Pablo
Pablo

Reputation: 21

Use regular expression in XSD element name

I'm trying to implement a XSD for my XML code.

    </transition>
    <!--The list of automata-->
    <Machine0/>
    <Machine1/>
    <Machine2/>
    <Machine3/>
  </automaton>
</structure>

The problem is with the Machine[i], the number of Machine[i] elements changes in each XML file.

I've tried with this code, but doesn't seem to work:

<xs:complexType>
    <xs:sequence>
        <xs:any minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:assertion test="every $x in * 
     satisfies matches(local-name($x), 'Machine[0-9]+')"/>
</xs:complexType> 

Upvotes: 2

Views: 1402

Answers (1)

kjhughes
kjhughes

Reputation: 111630

First, a few notes:

  1. Most importantly, if you still have design control over the naming of the Machine elements, do realize that you ought to have a very good reason for straying from the superior design pattern where element position is implied rather than represented explicitly in an element's name. I like xs:assert, so I don't like anyone giving the XSD WG members reasons to regret its inclusion in XSD 1.1. ;-)
  2. It's xs:assert, not xs:assertion (common typo).

  3. You'll want to anchor the start and end of your regex. (Unlike with xs:pattern, fn:matches() does not automatically anchor the start and end of its pattern.

  4. You'll need processContents="lax" or ="skip" unless you intend to define MachineN elements explicitly.


XSD 1.1

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
    elementFormDefault="qualified"
    vc:minVersion="1.1">

    <xs:element name="r" type="rType"/>

    <xs:complexType name="rType">
        <xs:sequence>
            <xs:any minOccurs="1" maxOccurs="unbounded" processContents="lax"/>
        </xs:sequence>
        <xs:assert test="every $x in * satisfies 
                         matches(local-name($x), '^Machine[0-9]+$')"/>
    </xs:complexType> 
</xs:schema>

Then, this XML

Valid case #0

<?xml version="1.0" encoding="UTF-8"?>
<r>
    <Machine0/>
    <Machine1/>
</r>

will be valid per your XSD, but these XML documents,

Invalid case #1

<?xml version="1.0" encoding="UTF-8"?>
<r>
    <xMachine0/>
    <Machine1/>
</r>

Invalid case #2

<?xml version="1.0" encoding="UTF-8"?>
<r>
    <Machine0x/>
    <Machine1/>
</r>

Invalid case #3

<?xml version="1.0" encoding="UTF-8"?>
<r>
    <Machine/>
    <Machine1/>
</r>

will be invalid, as requested.

Upvotes: 1

Related Questions