XSD中的可选键 [英] Optional key in XSD

查看:94
本文介绍了XSD中的可选键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在根元素上创建了key/keyref,以便基于指定的元素创建文档范围内的唯一性.

I've created a key/keyref on the root element in order to create document-wide uniqueness based on the specified element.

因此,通过.//foo/@name,在foo的所有实例中每次出现的@name都必须是唯一的.对于.//bar/@name同样.这似乎工作正常.这些分别由.//foo-ref/@name-ref.//bar-ref/@name-ref引用,它们也在根节点上定义.

Therefore, via .//foo/@name every occurrence of @name across all instances of foo must be unique; likewise for .//bar/@name. This seems to be working fine. These are referenced by .//foo-ref/@name-ref and .//bar-ref/@name-ref respectively, also defined at the root node.

但是,我已经收集到一个不能创建 optional 密钥的功能,这带来了一些问题.从语义上来说,根据符合条件的文档的性质,在foobar的每个单个实例上都不需要密钥. foo-ref/@name-ref的实例显然需要针对现有的foo/@name,但是对于foo没有@name来说在语义上不是无效的.

However, I've gathered that one cannot create an optional key, and this is presenting a bit of a problem. Semantically, by the nature of the conforming documents, a key is not required on every single instance of foo or bar. The instances of foo-ref/@name-ref would obviously need to target an existing foo/@name, but it isn't semantically invalid for a foo to be without a @name.

有什么解决方法吗?我不喜欢消费者必须为每个单个元素定义键的想法,而合理的情况是只有少数几个键需要它们.

Is there any work-around for this? I don't like the idea of consumers having to define a key for every single element, when reasonably only a handful will need them.

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

Here's the example schema (of course, I'm not deploying some foobar schema, but the structure is identical; this is just a testing schema I've been toying with)

<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引用,谁知道呢? (显然不是我)


Addendum

Just following up with my revisions thanks to @PetruGardea. So unique can be referenced by a keyref, who knew? (not me apparently)

<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或不存在).

Use xsd:unique; unlike a key, its matched value is either unique or nil (nil or not present).

示例:

<?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中的可选键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆