xsd - XSD 中的可选 key

标签 xsd key

我在根元素上创建了一个 key/keyref ,以便根据指定元素创建文档范围内的唯一性。

因此,通过 .//foo/@namefoo 的所有实例中出现的每个 @name 都必须是唯一的;对于 .//bar/@name 也是如此。这似乎运作良好。它们分别由 .//foo-ref/@name-ref.//bar-ref/@name-ref 引用,也在根节点处定义。

但是,我发现无法创建可选 key ,这带来了一些问题。从语义上讲,根据一致文档的性质,foobar 的每个实例都不需要 key 。 foo-ref/@name-ref 的实例显然需要以现有的 foo/@name 为目标,但它对于 foo 在语义上并不无效 不带 @name

有什么解决办法吗?我不喜欢消费者必须为每个单个元素定义一个键,而实际上只有少数人需要它们。

这是示例架构(当然,我没有部署一些 foobar 架构,但结构是相同的;这只是我一直在玩弄的测试架构)

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="ref">
        <xs:attribute name="name-ref" type="xs:string" use="required" />
    </xs:complexType>
    <xs:complexType name="obj">
        <xs:attribute name="name" type="xs:string" use="optional" />
    </xs:complexType>
    <xs:complexType name="foo">
        <xs:complexContent>
            <xs:extension base="obj">
                <xs:sequence>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="foo" type="foo" />
                        <xs:element name="bar" type="bar" />
                        <xs:element name="foo-ref" type="foo-ref" />
                        <xs:element name="bar-ref" type="bar-ref" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="foo-ref">
        <xs:complexContent>
            <xs:extension base="ref" />
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="bar">
        <xs:complexContent>
            <xs:extension base="obj">
                <xs:sequence>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="bar" type="bar" />
                        <xs:element name="qux" type="qux" />
                        <xs:element name="bar-ref" type="bar-ref" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="bar-ref">
        <xs:complexContent>
            <xs:extension base="ref" />
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="qux">
        <xs:simpleContent>
            <xs:extension base="xs:string" />
        </xs:simpleContent>
    </xs:complexType>
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="foo" type="foo" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
        <xs:key name="foo">
            <xs:selector xpath=".//foo" />
            <xs:field xpath="@name" />
        </xs:key>
        <xs:key name="bar">
            <xs:selector xpath=".//bar" />
            <xs:field xpath="@name" />
        </xs:key>
        <xs:keyref name="foo-ref" refer="foo">
            <xs:selector xpath=".//foo-ref" />
            <xs:field xpath="@name-ref" />
        </xs:keyref>
        <xs:keyref name="bar-ref" refer="bar">
            <xs:selector xpath=".//bar-ref" />
            <xs:field xpath="@name-ref" />
        </xs:keyref>
    </xs:element>
</xs:schema>
<小时/>

附录

感谢@PetruGardea,我正在跟进我的修订。所以 unique 可以被 keyref 引用,谁知道呢? (显然不是我)

<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="foo" type="foo" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
    <xs:keyref name="foo-ref" refer="foo">
        <xs:selector xpath=".//foo-ref" />
        <xs:field xpath="@name-ref" />
    </xs:keyref>
    <xs:keyref name="bar-ref" refer="bar">
        <xs:selector xpath=".//bar-ref" />
        <xs:field xpath="@name-ref" />
    </xs:keyref>
    <!--
        the use of xs:unique here, in lieu of xs:key allows for
        nullable "keys", retaining referential integrity with the
        above defined keyrefs. awesome possum.
    -->
    <xs:unique name="foo">
        <xs:selector xpath=".//foo" />
        <xs:field xpath="@name" />
    </xs:unique>
    <xs:unique name="bar">
        <xs:selector xpath=".//bar" />
        <xs:field xpath="@name" />
    </xs:unique>
</xs:element>

最佳答案

使用xsd:unique ;与键不同,它的匹配值要么是唯一的,要么是 nil(nil 或不存在)。

示例:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="root">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="uk" maxOccurs="unbounded">
                    <xsd:complexType>
                        <xsd:attribute name="name" type="xsd:string"/>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="fk" maxOccurs="unbounded">
                    <xsd:complexType>
                        <xsd:attribute name="name" type="xsd:string"/>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
        <xsd:unique name="uq">
            <xsd:selector xpath="uk"/>
            <xsd:field xpath="@name"/>
        </xsd:unique>
        <xsd:keyref name="fk" refer="uq">
            <xsd:selector xpath="fk"/>
            <xsd:field xpath="@name"/>
        </xsd:keyref>
    </xsd:element>
</xsd:schema>

示例(有效)XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <uk name="name1"/>
    <uk />
    <fk/>
    <fk name="name1"/>
</root>

关于xsd - XSD 中的可选 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15842736/

相关文章:

visual-studio - 如何在 Visual Studio 中导出和导入 XSD 文件?

xml - XSD 允许双倍减半

ios - 对象可以隐藏在 NSDictionary 中吗?不从字典中删除只是隐藏

xml - 如何将 XML 从一个 XSD 转换为另一个 XSD?

xml - XSD 对特定类型的兄弟元素的属性的唯一约束

java - 如何访问另一个 xml 元素中的 xml 元素(JAXB 绑定(bind)

arrays - 了解如何在 lua 中访问表数组中的值

ios - 打印 NSDictionary 的键而不是值

json - 如何在 jq 中传播对象的属性?

authentication - 私钥类型之间的区别?