0

I have a struggle with XSD schema. I want to put a restriction where only one of the element within a node can have the cetrain arttribute and don't affect the other one.

Giving you an example of valid and invalid XML files would be better:

Valid XML

The tag someone must contain the attriubte @id, but the only one of them would be honored to have the @status attribute with the captain value.

<node>
    <someone id="01">Alex</someone>
    <someone id="02">Amanda</someone>
    <someone id="03" status="captain">Bob</someone>
    <someone id="04">Costa</someone>
</node>

Invalid XML

The following ones are invalid. There is no way to have two ones with @status.

<node>
    <someone id="01" status="captain">Alex</someone>
    <someone id="02">Amanda</someone>
    <someone id="03" status="captain">Bob</someone>
    <someone id="04">Costa</someone>
</node>

And also not possible to skip the @id.

<node>
    <someone status="captain">Alex</someone>
    <someone id="01">Amanda</someone>
    <someone id="02">Costa</someone>
</node>

My actual XSD

I have the following piece of xsd file so far, however I have no idea how to apply the restriction described above.

<xsd:complexType name="nodeType">
    <xsd:sequence>
        <xsd:element name="someone" type="xsd:string"/>
    </xsd:sequence>
    <xsd:attribute name="id" type="idType" use="required"/>
</xsd:complexType>

I am thankful for the help. I think the way using would do the work better and easier, however I have a really little experience with that.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183

2 Answers2

2

Can't be done with XSD 1.0. Very easy to do with XSD 1.1 using assertions. Not sure I understand the condition exactly, but it's something

<xs:assert test="count(*/@status)=1"/>
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
1

Below is the required schematron:

<?xml version="1.0" encoding="utf-8"?>
<iso:schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
    queryBinding='xslt2' schemaVersion='ISO19757-3'>
    <iso:pattern id="check">
        <iso:rule context="/node/someone">
            <iso:assert test= "count(.[@status='captain']) = 1">
                You cannont have more than one &lt;someone&gt; with status attribute = captain
            </iso:assert>
            <iso:assert test= "boolean(@id)">
                id is required attribute in &lt;someone&gt;.
            </iso:assert>
        </iso:rule>
    </iso:pattern>
</iso:schema>

You might want to check ph-schematron library for Java to test it out.

You can find the working code which uses the above schematron and your sample xml here.

MohamedSanaulla
  • 6,112
  • 5
  • 28
  • 45