缩短 XSD

Shorten the XSD

我有一个XML和一个对应的XSD如下:

myXSD.xsd :

<?xml version="1.0"  encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com/myXSD"
    xmlns="http://www.example.com/myXSD"
    elementFormDefault="qualified">

    <xs:element name="RootElem">
        <xs:complexType>
            <xs:sequence>

                <xs:element name="Insider1">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element ref="Internal" maxOccurs="unbounded" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

                <xs:element name="Insider2">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element ref="Internal" maxOccurs="unbounded" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

                <xs:element name="Insider3">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element ref="Internal" maxOccurs="unbounded" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Internal-low">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="myString" type="xs:string" maxOccurs="unbounded"></xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Internal">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Step" type="xs:string"></xs:element>
                <xs:element ref="Internal-low" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

myXML.xml :

<?xml version="1.0" encoding="UTF-8"?>

<RootElem xmlns="http://www.example.com/myXSD"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.com/myXSD myXSD.xsd">
    <Insider1>
        <Internal>
            <Step>My step 1</Step>
            <Internal-low>
                <myString>My string 1 for step 1</myString>
            </Internal-low>
        </Internal>
        <Internal>
            <Step>My step 2</Step>
            <Internal-low>
                <myString>My string 1 for step 2</myString>
            </Internal-low>
        </Internal>
        <Internal>
            <Step>My step 3</Step>
            <Internal-low>
                <myString>My string 1 for step 3</myString>
                <myString>My string 2 for step 3</myString>
            </Internal-low>
        </Internal>
    </Insider1>
    <Insider2>
        <Internal>
            <Step>My step 1</Step>
            <Internal-low>
                <myString>My string 1 for step 1</myString>
            </Internal-low>
        </Internal>
        <Internal>
            <Step>My step 2</Step>
            <Internal-low>
                <myString>My string 1 for step 2</myString>
            </Internal-low>
        </Internal>
        <Internal>
            <Step>My step 3</Step>
            <Internal-low>
                <myString>My string 1 for step 3</myString>
                <myString>My string 2 for step 3</myString>
            </Internal-low>
        </Internal>
    </Insider2>
    <Insider3>
        <Internal>
            <Step>My step 1</Step>
            <Internal-low>
                <myString>My string 1 for step 1</myString>
            </Internal-low>
        </Internal>
        <Internal>
            <Step>My step 2</Step>
            <Internal-low>
                <myString>My string 1 for step 2</myString>
            </Internal-low>
        </Internal>
        <Internal>
            <Step>My step 3</Step>
            <Internal-low>
                <myString>My string 1 for step 3</myString>
                <myString>My string 2 for step 3</myString>
            </Internal-low>
        </Internal>
    </Insider3>

</RootElem>

这里一切正常。问题出在 InsiderX 元素上。我的实际 XSD 中大约有 10 个 InsiderX 个元素,这些元素可能会随着时间的推移而增加。所以我需要压缩 XSD 代码,以便添加或删除任何 InsiderX 元素更简单,因为这样做现在需要 adding/removing 7 行冗余代码。我怎样才能确保每个 InsiderX 元素中只有一个出现在我的 XML.

我还想知道 XSD 中有哪些其他选项可以替换 <xs:sequence>。我不想替代这个,但想知道其他可能的选择是什么,比如 <xs:choice>.

我认为这是不可撤销的,处理此问题的更好方法是在您的 xml 中设置 :

<Insider name="Insider1">

而不是

<Insider1>

编辑:(限制名称属性值)

<attribute name="name">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="Insider[0-9]*"/>
        </xs:restriction>
    </xs:simpleType>
</attribute>

I need to compress the XSD code so that adding or removing any InsiderX element is simpler as doing so now requires adding/removing 7 lines of redundant code

您可以通过创建这样的可重用类型来缩短 XSD。

<xs:complexType name="InsiderXType">
    <xs:sequence>
        <xs:element ref="Internal" maxOccurs="unbounded" />
    </xs:sequence>
</xs:complexType>

<xs:element name="RootElem">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Insider1" type="InsiderXType"/>
            <xs:element name="Insider2" type="InsiderXType"/>
            <xs:element name="Insider3" type="InsiderXType"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

how can I make sure that one and only one of each of the InsiderX element occurs in my XML

您已经使用原始架构涵盖了此场景。通过复制 Insider1 节点来修改您的 XML 文档,例如像这样

<Insider1>
    ...
</Insider1>
<Insider1>
    ...
</Insider1>
<Insider2>
   ...

并尝试根据您的模式验证这一点。您会收到类似这样的错误:cvc-complex-type.2.4.a:发现以元素 'Insider1' 开头的无效内容。应为“{"http://www.example.com/myXSD":Insider2}”之一。

I would like to know what are other options in a XSD to replace <xs:sequence>

好吧,我不确定如何回答这个问题,因为这个问题真的太宽泛了,但是请查看 XML Schema specification 以了解复杂的类型定义。它说您可以使用 groupallchoice 而不是序列。我希望这会让你走上正轨。