xml - XSD key /keyref : hierarchical key structure

标签 xml schema xsd

我正在尝试使用 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>

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

然后会有一个引用者列表,其中包含对特定父项和子项的外键引用。

我可以根据需要定义键,只需将它们放在正确的元素上:根元素上的 parentKey 约束和父元素上的 childKey 约束。我还可以毫不费力地将 keyref 定义为 parentKey。

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

然后我尝试定义一个组合键(在 root 上):

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

如果在父项下定义了多个子项,则此操作失败。这是基于 XSD 1.1 spec 的正确行为,第 3.11.4 节,第 3 项,其中规定键必须最多匹配每个字段定义的一个节点。

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

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

最佳答案

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

  <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 /keyref : hierarchical key structure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/891324/

相关文章:

xml - 验证中的 "Elements ... does not resolve to a(n) type definition"

c# - 如何在 WCF 中返回 DataSet (xsd)

maven-2 - 如何告诉 jaxb/Maven 生成多个模式包?

xml - XSD:声明 xs:integer 数据类型时允许空值的选项

JAXB 架构到 Java 不同的 XmlRootElement 名称和类名称

java - 将 SQLite 数据库导出到 Android 中的 XML 文件

Java/XML问题

android - 如何计算布局中的 View 数量

java - SessionFactory getCurrencSesion 不适用于 Autowiring

mysql - 数据库模式 - 按对象或数据组织?