开发者

Restrict order of XML elements based on attribute

I have the following XML:

<?xml version="开发者_StackOverflow1.0"?>

<coll xmlns="http://www.example.org/coll" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/coll coll.xsd">

    <collection>
        <item action="remove">1</item>
        <item action="add">2</item>
        <item action="add">3</item>
    </collection>

    <collection>
        <item action="add">2</item>
        <item action="remove">1</item>
        <item action="add">3</item>
    </collection>

</coll>   

And an XSD:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/coll"
    xmlns:tns="http://www.example.org/coll" elementFormDefault="qualified">

    <element name="coll" type="tns:coll">
    </element>

    <complexType name="coll">
        <sequence>
            <element name="collection" type="tns:collection" minOccurs="0" maxOccurs="unbounded"></element>
        </sequence>
    </complexType>

    <complexType name="collection">
        <sequence>
            <element name="item" type="tns:item" minOccurs="0" maxOccurs="unbounded"></element>
        </sequence>
    </complexType>

    <complexType name="item">
        <simpleContent>
            <extension base="string">
                <attribute name="action">
                    <simpleType>
                        <restriction base="string">
                            <enumeration value="add"></enumeration>
                            <enumeration value="remove"></enumeration>
                        </restriction>
                    </simpleType>
                </attribute>
            </extension>
        </simpleContent>
    </complexType>

</schema>

I would like to restrict the order of the item elements such that the removes always comes before the adds. I.e. the first collection is valid but the second one is invalid.

I've tried with two item elements, one with an add_item type and one with remove_item. But this fails to validate the XSD with the error that I can not have two elements of the same name with different types.

Any ideas? Or is it even possible?


The only way this is possible (with XSD) would be by refactoring your schema to use the action as the element name instead of an attribute:

<collection>
    <remove>1</remove>
    <add>2</add>
    <add>3</add>
</collection>

That way, you can use a sequence in your schema to determine the order.

On a more general note: Your schema design looks a bit mixed up. Your element names seem to describe a state (collection, item), yet your attributes on item seem to carry the actual information about an action your code is (presumably) to take. If you have a choice about the design, you might want to think about a slight redesign.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜