I am working on an XML Schema (message.xsd
) describing the structure of a message.
Here are the expected children of the <message>
element (the root):
<from>
: Contains the address of the sender. Occurs 0 or 1 times.<to>
: Contains the address of the recipient. Occurs 0 or more times.<cc>
: Contains the address of the recipient in copy. Occurs 0 or more times.<subject>
: Contains the subject of the message. Occurs 0 or 1 times.<body>
: Contains the body of the message. Occurs 0 or 1 times.
The order of elements does not matter, it means that they can be in any order.
Here is a first simple XML example (message-1.xml
) that has to be valid:
$ xmllint --schema message.xsd message-1.xml
<?xml version="1.0"?>
<message xmlns="http://yugiohjcj.1s.fr/message">
<from>[email protected]</from>
<to>[email protected]</to>
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
</message>
message-1.xml validates
And it is valid!
Here is a second more complex XML example (message-2.xml
) that has to be valid:
$ xmllint --schema message.xsd message-2.xml
<?xml version="1.0"?>
<message xmlns="http://yugiohjcj.1s.fr/message">
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<from>[email protected]</from>
<to>[email protected]</to>
<to>[email protected]</to>
<cc>[email protected]</cc>
<cc>[email protected]</cc>
</message>
message-2.xml validates
And it is valid!
Here is a third XML example (message-3.xml
) that has to be not valid:
$ xmllint --schema message.xsd message-3.xml
<?xml version="1.0"?>
<message xmlns="http://yugiohjcj.1s.fr/message">
<from>[email protected]</from>
<from>[email protected]</from>
<to>[email protected]</to>
<subject>How are you?</subject>
<subject>How are you again?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<body>Hello. How are you again? Thank you. Best regards.</body>
</message>
message-3.xml validates
But it is valid! That's the problem.
Here is my XML Schema (message.xsd
):
$ cat message.xsd
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://yugiohjcj.1s.fr/message" targetNamespace="http://yugiohjcj.1s.fr/message" elementFormDefault="qualified">
<xs:element name="message">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="from"/>
<xs:element name="to"/>
<xs:element name="cc"/>
<xs:element name="subject"/>
<xs:element name="body"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I guess that I need to set the maxOccurs
attribute to the value 1
somewhere or maybe I need to combine differently the <xs:sequence>
and <xs:choice>
elements but I have not found how to reach my goal.
Any idea how to fix this XML Schema please?
Thank you.
Best regards.
Edit: OK I found a workaround to my problem by using Relax NG instead of XSD 1.0. It works fine and it is compatible with libxml2.
Here is my message.rng
file:
$ cat message.rng
<element name="message" xmlns="http://relaxng.org/ns/structure/1.0">
<interleave>
<zeroOrMore>
<element name="from">
<text/>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="to">
<text/>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="cc">
<text/>
</element>
</zeroOrMore>
<optional>
<element name="subject">
<text/>
</element>
</optional>
<optional>
<element name="body">
<text/>
</element>
</optional>
</interleave>
</element>
And here is the result on my 3 XML examples (message-1.xml
, message-2.xml
and message-3.xml
):
$ xmllint --relaxng message.rng message-1.xml
<?xml version="1.0"?>
<message>
<from>[email protected]</from>
<to>[email protected]</to>
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
</message>
message-1.xml validates
$ xmllint --relaxng message.rng message-2.xml
<?xml version="1.0"?>
<message>
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<from>[email protected]</from>
<to>[email protected]</to>
<to>[email protected]</to>
<cc>[email protected]</cc>
<cc>[email protected]</cc>
</message>
message-2.xml validates
$ xmllint --relaxng message.rng message-3.xml
<?xml version="1.0"?>
<message>
<from>[email protected]</from>
<from>[email protected]</from>
<to>[email protected]</to>
<subject>How are you?</subject>
<subject>How are you again?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<body>Hello. How are you again? Thank you. Best regards.</body>
</message>
Relax-NG validity error : Extra element subject in interleave
message-3.xml:7: element subject: Relax-NG validity error : Element message failed to validate content
message-3.xml fails to validate