XML Schema 键/keyref - 如何使用它们?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4491983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:26:54  来源:igfitidea点击:

XML Schema key/keyref - how to use them?

xmlxsdreferenceschemajaxb

提问by kostja

Long story short : i would like to know how to use the key/keyref from XSD to let elements have references to each other. it has to have a form of an example, using a simple xsd and an XML.

长话短说:我想知道如何使用 XSD 中的 key/keyref 来让元素相互引用。它必须具有示例形式,使用简单的 xsd 和 XML。

Long story : I am familiar with usage of ID/IDREF. I use those to connect elements for JAXB. I have been told repeatedly that the key/keyref construct in XSD offers enhanced flexibility for inter-element referencing. I have consulted the OReilly XML Schema book, that seems to teach everything about correct definition of key/keyref and how it is similar to the ID/IDREF (but better) and doesn't give a simple example of its use. It doesn't seem to be similar, because you define the ID as an attribute in one element and the IDREF in another element and voila. But key/keyref have to be defined in a common ancestor of the referencing and the referenced element (AFAIK)...

长话短说:我熟悉 ID/IDREF 的用法。我使用这些来连接 JAXB 的元素。我一再被告知 XSD 中的 key/keyref 构造为元素间引用提供了增强的灵活性。我查阅了OReilly XML Schema book,它似乎教了关于正确定义 key/keyref 的所有内容,以及它如何与 ID/IDREF 相似(但更好),并且没有给出其使用的简单示例。它似乎并不相似,因为您将 ID 定义为一个元素中的属性,而将 IDREF 定义为另一个元素中的属性,瞧。但是 key/keyref 必须在引用和被引用元素 (AFAIK) 的共同祖先中定义...

I use the XSD files to generate JAXB-bound Java classes with XJC

我使用 XSD 文件通过 XJC 生成 JAXB 绑定的 Java 类

I have searched for how-tos, tutorials and examples, but google gives me scraps. same for searches on SO (also with google and inclusive search with '+' ).

我搜索了操作方法、教程和示例,但谷歌给了我一些碎片。对 SO 的搜索也是如此(也可以使用 google 和包含 '+' 的搜索)。

In order to make everyone's lives easier i have prepared an XSD with already defined key/keyref pair as i have understood it.

为了让每个人的生活更轻松,我准备了一个 XSD,其中已经定义了我所理解的密钥/keyref 对。

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="referenced">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:string" />
                </xs:complexType>
            </xs:element>
            <xs:element name="owner">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:string" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="aKey">
        <xs:selector xpath="owner" />
        <xs:field xpath="@id" />
    </xs:key>
    <xs:keyref name="aKeyRef" refer="aKey">
        <xs:selector xpath="referenced" />
        <xs:field xpath="@id" />
    </xs:keyref>
</xs:element>

How would a piece of XML look like, with an 'owner'-element referencing a 'referenced'-element?

如果“所有者”元素引用“引用”元素,那么一段 XML 会是什么样子?

EDIT : applied the change proposed by Tom W, changing the xpath attribute of the key element to "owner". JAXB (XJC) still doesnt care though.

编辑:应用 Tom W 提出的更改,将关键元素的 xpath 属性更改为“所有者”。JAXB (XJC) 仍然不在乎。

Thank you

谢谢

回答by Tom W

There is no special syntax in the instance document. It is simply required that the keyref node matches an extant key node. Validation will tell you whether or not the key constraint is satisfied.

实例文档中没有特殊语法。只需要 keyref 节点与现存的 key 节点相匹配。验证将告诉您是否满足关键约束。

RE your code:

重新你的代码:

I've only just started dabbling with keys myself, but I think I've spotted an error in yours - aKeyshould look like:

我自己才刚刚开始涉足钥匙,但我想我发现了您的错误 -aKey应该如下所示:

<xs:key name="aKey">
    <xs:selector xpath="owner" />
    <xs:field xpath="@id" />
</xs:key>

Furthermore - this is a gotcha - key constraints don't recognise the default namespace. You must always prefix every part of the selectorxpath with the namespace prefix of the element you're looking up. If you don't have a namespace prefix - tough, you'll need to add one. This is a limitation of the standard.

此外 - 这是一个陷阱 - 键约束无法识别默认命名空间。您必须始终selector使用您正在查找的元素的名称空间前缀作为xpath 的每个部分的前缀。如果您没有命名空间前缀 - 很难,您需要添加一个。这是标准的限制。

回答by bdoughan

The JAXB spec does not explicitly cover key/keyref. However JAXB implemenations such as EclipseLink MOXy(I'm the tech lead) have extensions for this. Our upcoming 2.2 release provides a means to specify this kind of relationship via annotations (I'll put together an example). Below is a link to how it can be done using the current release.

JAXB 规范没有明确涵盖 key/keyref。但是,诸如EclipseLink MOXy(我是技术负责人)之类的 JAXB 实现对此进行了扩展。我们即将发布的 2.2 版本提供了一种通过注释指定这种关系的方法(我将整理一个示例)。以下是如何使用当前版本完成此操作的链接。

For more information see:

有关更多信息,请参阅:

UPDATE

更新

I was hoping to get an example included with the answer, but I am running out of time before I leave on vacation. Below is an example from our design documents that demonstrates the concept:

我希望得到一个包含在答案中的例子,但在我休假之前我的时间已经不多了。以下是我们设计文档中的一个示例,用于演示该概念:

回答by UberschallSamsara

I found this thread searching for the same thing the OP was searching for - a simple usage example of the <xs:key>element. All the JAXB stuff was greek to me, and a distraction. For others finding this thread later, here's a simple example posted on MSDN a couple years after the OP asked the question here on SO:

我发现该线程正在搜索 OP 正在搜索的相同内容 -<xs:key>元素的一个简单使用示例。所有 JAXB 的东西对我来说都是希腊语,让人分心。对于稍后找到此线程的其他人,这是在 OP 在 SO 上提出问题几年后,在 MSDN 上发布的一个简单示例:

https://msdn.microsoft.com/en-us/library/ms256101%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

https://msdn.microsoft.com/en-us/library/ms256101%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

In case the MSDN link changes, the breadcrumb path was:

如果 MSDN 链接发生变化,面包屑路径是:

https://msdn.microsoft.com/librarythen click "Switch to Library TOC view", and drill down through:

https://msdn.microsoft.com/library然后单击“切换到库目录视图”,并向下钻取:

MSDN Library > .NET development > .NET Framework 4.6 and 4.5 > Development Guide > Data and Modeling > XML Standards Reference > XML Schemas (XSD) Reference > XML Schema Elements > <xsd:key> Element

MSDN 库 > .NET 开发 > .NET Framework 4.6 和 4.5 > 开发指南 > 数据和建模 > XML 标准参考 > XML 架构 (XSD) 参考 > XML 架构元素 > <xsd:key> 元素

回答by kitsune

Please, try to see this key/keyref tutorial.

请尝试查看此密钥/密钥引用教程

The colored text is very helpful.

彩色文字很有帮助。

回答by markusk

JAXB doesn't support references by means of xs:keyor xs:keyref. The specification states that these constraints may be checked during validation, but they have no effect on data.

JAXB 不支持通过xs:key或 进行引用xs:keyref。规范指出,这些约束可以在验证期间检查,但它们对数据没有影响。

However, you can achieve this (more or less) by using xs:IDand xs:IDREFinstead. For an introduction, see the chapters 2.2.15 Referring to Another XML Elementand 4.3 Assembling Data with Links (ID, IDREF)in the JAXB Tutorialby Wolfgang Laun.

但是,您可以通过使用xs:IDandxs:IDREF来实现(或多或少)。有关介绍,请参阅Wolfgang Laun的 J AXB 教程中的章节2.2.15 引用另一个 XML 元素4.3 使用链接(ID、IDREF)组装数据

For your sample XSD, this would meaning changing the element definition to

对于您的示例 XSD,这意味着将元素定义更改为

<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="referenced">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:ID" />
                </xs:complexType>
            </xs:element>
            <xs:element name="owner">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:IDREF" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Note that identifiers with the xs:IDtype are required to be globally unique in the XML document. In other words, you cannot have the same ID for two different elements in the same XML file, even if the elements are of different types.

请注意,具有该xs:ID类型的标识符在 XML 文档中必须是全局唯一的。换句话说,同一个 XML 文件中的两个不同元素不能具有相同的 ID,即使这些元素的类型不同。

By default, an element or attribute of type xs:IDREFbinds to java.lang.Object. If you know in advance what type the referenced object will be, you can customize the mapping, either by adding JAXB annotations to the schema or through an external binding declaration (e.g., xjc -b bindings.xjb).

默认情况下,类型的元素或属性xs:IDREF绑定到java.lang.Object. 如果您事先知道被引用对象的类型,您可以自定义映射,方法是向模式添加 JAXB 注释或通过外部绑定声明(例如,xjc -b bindings.xjb)。

Example using JAXB schema annotations (not tested):

使用 JAXB 模式注释的示例(未测试):

<xs:element name="owner">
    <xs:complexType>
        <xs:attribute name="id" type="xs:IDREF">
            <xs:annotation>
                <xs:appinfo>
                    <jaxb:property>
                        <jaxb:baseType name=”SomeType”/>
                    </jaxb:property>
                </xs:appinfo>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>
</xs:element>

Example using an external bindings declaration (not tested):

使用外部绑定声明的示例(未测试):

<jaxb:bindings node="//xs:element[@name='owner']//xs:attribute[@name='id']”>
    <jaxb:property>
        <jaxb:basetype name="SomeType"/>
    </jaxb:property>
</jaxb:bindings>