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

<?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>

a每个父项都有一个(全局)唯一键,由parent key定义。每个子项都有由child key定义的键,但childkey仅在其包含的父项的范围内是唯一的。
然后会有一个引用列表,其中包含对特定父项和子项的外键引用。
我可以根据需要定义键,只需将它们放在正确的元素上:根元素上的parentkey约束和父元素上的childkey约束。我还可以毫无困难地将keyref定义为parentkey。
在尝试将keyref定义为childkey时会出现问题。我试着在根元素上定义一个简单的keyref到childkey,但是这不起作用,因为我看不到在正确的父子树下只选择子元素的方法。(至少,eclipse验证器总是根据文档中最后一个父子树的内容进行验证……)。
然后我尝试定义一个复合键(在根上),使用:
选择器=父
字段=@parentkey
field=child/@childkey字段
如果父项下定义了多个子项,则此操作将失败。这是基于XSD 1.1 spec第3.11.4节第3项的正确行为,该项说明密钥必须在每个字段定义中最多匹配一个节点。
只是重申一下:如果我强制子密钥是全局唯一的,这很容易实现;困难在于引用本地唯一的子密钥。
有没有XSD大师有主意?
作为参考,下面是一个示例xsd,其中注释掉了一个失败的childkey keyref:
<?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>

最佳答案

从孩子身上提到父母怎么样?即使有许多子项,也将只有一个父项,并且组合(父项,子项)将创建全局唯一键,即使子项仅在其父项中唯一:

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

这在xmllint中不起作用,即使规范似乎没有显式地禁止字段使用它-仅适用于选择器:3.11.4,(2)说选择器不能是祖先(它只能是上下文节点或后代)。
啊,这是关键所在(看看具体的语法):允许的xpath表达式非常有限,只是不包括“.”“http://www.w3.org/TR/xmlschema-1/#c-fields-xpaths
所以,对不起,这不能回答你的问题,但也许它能给你一些建议。

关于xml - XSD key / key 引用:分层 key 结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/891324/

10-12 01:02