1

我正在尝试开发一个 XML Schema 文件来验证一个Person元素。我们的应用程序要求一个人有一个FirstName并且LastName不关心他们进入的顺序。它还允许将其他元素放在Person元素下。所以以下是有效的:

<person>
    <firstName>Jon</firstName>
    <lastName>Smith</lastName>
</person>

<person>
    <lastName>Smith</lastName>
    <firstName>Jon</firstName>
</person>

<person>
    <title>Mr</title>
    <firstName>Jon</firstName>
    <lastName>Smith</lastName>
</person>

<person>
    <title>Mr</title>
    <lastName>Smith</lastName>
    <firstName>Jon</firstName>
    <suffix>CEng</suffix>
</person>

<person>
    <title>Mr</title>
    <lastName>Smith</lastName>
    <middleInitial>G</middleInitial>
    <firstName>Jon</firstName>
    <suffix>CEng</suffix>
</person>

但是,以下内容无效,因为它没有firstName

<person>
    <title>Mr</title>
    <lastName>Smith</lastName>
    <suffix>CEng</suffix>
</person>

我尝试创建一个像这样的复杂类型:

<xsd:element name="person">
    <xsd:complexType>
        <xsd:all>
            <xsd:element minOccurs="1" maxOccurs="1" name="firstName" />
            <xsd:element minOccurs="1" maxOccurs="1" name="lastName"/>
            <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip" />
        </xsd:all>
    </xsd:complexType>
</xsd:element>

但显然any是不允许进去all的。是否可以让 XML Schema 进行此验证?如果有怎么办?

4

1 回答 1

1

如果您有 XML Schema 1.1 验证器:

<xsd:element name="person">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip" />
        </xsd:sequence>
    </xsd:complexType>
    <xsd:assert test="firstName and lastName"/>
</xsd:element>

在 xsd 1.1 中,在 xsd:all 中包含 xsd:any 是有效的,但如果您未指定的元素与 firstName 和 lastName 位于相同的命名空间中,则仍可能导致错误,因为内容模型会模棱两可。但是 xsd:assert 会起作用。

在 xsd 1.0 中,您可以将元素可以具有的所有顺序指定为带有选项的序列。但是,除了 firstName 和 lastName 之外的元素需要位于不同的命名空间中,否则您的架构上会出现此“不明确的内容模型”错误。我不确定您是否可以在数据中使用此“其他命名空间”约束,但我认为这是在 Xml Schema 版本 1.0 中对此进行建模的唯一方法。

XSD

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

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:element name="persons">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="person" minOccurs="1" maxOccurs="unbounded" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="firstName" />
    <xsd:element name="lastName" />
    <xsd:element name="person">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip" namespace="##other" />
                <xsd:choice>
                    <xsd:sequence>
                        <xsd:element minOccurs="1" maxOccurs="1" ref="firstName" />
                        <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip" namespace="##other" />
                        <xsd:element minOccurs="1" maxOccurs="1" ref="lastName" />
                    </xsd:sequence>
                    <xsd:sequence>
                        <xsd:element minOccurs="1" maxOccurs="1" ref="lastName" />
                        <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip" namespace="##other" />
                        <xsd:element minOccurs="1" maxOccurs="1" ref="firstName" />
                    </xsd:sequence>
                </xsd:choice>
                <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip" namespace="##other" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

输入 XML

<?xml version="1.0"?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd" xmlns:o="urn:foobar">
    <person>
        <firstName>Jon</firstName>
        <lastName>Smith</lastName>
    </person>

    <person>
        <lastName>Smith</lastName>
        <firstName>Jon</firstName>
    </person>

    <person>
        <o:title>Mr</o:title>
        <firstName>Jon</firstName>
        <lastName>Smith</lastName>
    </person>

    <person>
        <o:title>Mr</o:title>
        <lastName>Smith</lastName>
        <firstName>Jon</firstName>
        <o:suffix>CEng</o:suffix>
    </person>

    <person>
        <o:title>Mr</o:title>
        <lastName>Smith</lastName>
        <o:middleInitial>G</o:middleInitial>
        <firstName>Jon</firstName>
        <o:suffix>CEng</o:suffix>
    </person>
</persons>
于 2014-01-30T17:00:50.303 回答