XSD key/keyref:分层密钥结构 [英] XSD key/keyref: hierarchical key structure

查看:42
本文介绍了XSD key/keyref:分层密钥结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 xs:key 和 xs:keyref 定义在 XML 模式上定义一些外键约束.我希望文档的结构按以下方式分层:

I'm trying to define some foreign key constraints on an XML schema using xs:key and xs:keyref definitions. I want the structure of the document to be hierarchical in the following way:

<?xml version="1.0" encoding="UTF-8"?>
<tns:root xmlns:tns="http://www.example.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/ SampleSchema.xsd ">
  <parent parentKey="parent1">
    <child childKey="child1"/>
    <child childKey="child2"/>
  </parent>
  <parent parentKey="parent2">
    <child childKey="child1"/>
    <child childKey="child2"/>
  </parent>
  <referrer parentRef="parent1" childRef="child2"/>
</tns:root>

每个父级都有一个(全局)唯一键,由 parentKey 定义.每个子项都有 childKey 定义的键,但 childKey 仅在其包含的父项范围内唯一.

A each parent has a (globally) unique key, defined by parentKey. Each child has key defined by childKey, but childKey is only unique within the scope of its containing parent.

然后有一个引用列表,其中包含对特定父级和子级的外键引用.

There is then a list of referrers with foreign key references to a particular parent and child.

我可以根据需要定义键,只需将它们放在正确的元素上:根元素上的 parentKey 约束和父元素上的 childKey 约束.我也可以毫无困难地将 keyref 定义为 parentKey.

I'm able to define the keys as I want, simply by putting them on the correct element: the parentKey constraint on the root element, and the childKey constraint on the parent element. I can also define the keyref to parentKey without difficulty.

尝试定义 childKey 的 keyref 时会出现问题.我尝试在 childKey 的根元素上定义一个简单的 keyref,但这不起作用,因为我看不到仅选择正确父子树下的子元素的方法.(至少,Eclipse 验证器总是简单地根据文档中最后 父子树的内容进行验证......).

The problems arise when trying to define a keyref to childKey. I tried defining a simple keyref on the root element to childKey, but that doesn't work since I see no way to select only the child elements under the proper parent subtree. (The Eclipse validator, at least, always simply validates against the content of the last parent subtree in the document...).

然后我尝试定义一个复合键(在 root 上),使用:

I then tried defining a composite key (on root), with:

  • 选择器 = 父
  • field = @parentKey
  • field = child/@childKey

如果在父项下定义了多个子项,则会失败.这是基于 XSD 1.1 规范,第 3.11.4 节,项目的正确行为3,它规定键必须与每个字段定义最多匹配一个节点.

This fails if there is more than one child defined under the parent. That is the correct behavior based on the XSD 1.1 spec, section 3.11.4, item 3, which states that the key has to match at most one node per field definition.

再次重申:如果我强制 childKeys 是全局唯一的,这很容易实现;困难在于引用本地唯一的 childKeys.

Just to reiterate: if I force childKeys to be globally unique, this is easy to implement; the difficulty is around referencing locally unique childKeys.

有没有 XSD 大师有想法?

Any XSD masters out there have an idea?

作为参考,这里是一个示例 XSD,注释掉了一个失败的 childKey keyref:

For reference, here is a sample XSD, with a failed childKey keyref commented out:

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

    <element name="root">
        <complexType>
            <sequence>
                <element name="parent" maxOccurs="unbounded" minOccurs="1">
                    <complexType>
                        <sequence>
                            <element name="child" maxOccurs="unbounded" minOccurs="1">
                                <complexType>
                                    <attribute name="childKey" type="string" use="required"/>
                                </complexType>
                            </element>
                        </sequence>
                        <attribute name="parentKey" type="string" use="required"/>
                    </complexType>
                    <key name="childKeyDef">
                        <selector xpath="child"/>
                        <field xpath="@childKey"/>
                    </key>
                </element>
                <element name="referrer" maxOccurs="unbounded" minOccurs="1">
                    <complexType>
                        <attribute name="parentRef" type="string"/>
                        <attribute name="childRef" type="string"/>
                    </complexType>
                </element>
            </sequence>
        </complexType>
        <key name="parentKeyDef">
            <selector xpath="parent"/>
            <field xpath="@parentKey"/>
        </key>
        <keyref name="parentKeyRef" refer="tns:parentKeyDef">
            <selector xpath="referrers"/>
            <field xpath="@parentRef"/>
        </keyref>
<!--        <keyref name="childKeyRef" refer="tns:childKeyDef">-->
<!--            <selector xpath="referrers"/>-->
<!--            <field xpath="@childRef"/>-->
<!--        </keyref>-->
    </element>
</schema>

推荐答案

如何从子引用父?即使有很多孩子,也只有一个父级,并且组合 (parent,child) 会创建一个全局唯一键,即使子键仅在其父级内是唯一的:

How about referring to the parent from the child? Even if many children, there will only be one parent, and combining the (parent,child) creates a globally unique key, even though the child key is only unique within its parent:

  <key name="childKeyDef">
    <selector xpath="child"/>
    <field xpath="@childKey"/>
    <field xpath="../@parentKey"/>
  </key>

这在 xmllint 中不起作用,即使规范似乎没有明确禁止字段 - 仅适用于选择器:3.11.4, (2) 说 selector 不能是祖先(它只能是上下文节点或后代.)

This doesn't work in xmllint, even though the spec doesn't seem to explicitly disallow this for fields - only for selectors: 3.11.4, (2) says the selector can't be an ancestor (it can only be the context node or descendants.)

啊,这是棺材里的钉子(看具体的语法):允许的 XPath 表达式非常有限,根本不包括.."http://www.w3.org/TR/xmlschema-1/#c-fields-xpaths

Ah, here's the nail in the coffin (looking at specific syntax): the XPath expressions allowed are very limited, and simply don't include ".." http://www.w3.org/TR/xmlschema-1/#c-fields-xpaths

所以,抱歉,这不能回答你的问题,但也许会给你一些想法.

So, sorry, this doesn't answer your question, but maybe it will give you some ideas.

这篇关于XSD key/keyref:分层密钥结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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