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

发布于 2024-10-08 19:24:50 字数 1787 浏览 0 评论 0原文

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

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

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

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

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

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

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

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

谢谢

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.

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)...

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

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 '+' ).

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

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

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

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

冧九 2024-10-15 19:24:50

我发现该线程正在搜索 OP 正在搜索的相同内容 - 元素的简单使用示例。所有 JAXB 的东西对我来说都是希腊语,而且会分散我的注意力。对于后来发现这个帖子的其他人来说,这里有一个简单的例子,几年后OP在SO上提出这个问题后发布在MSDN上:

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

如果 MSDN 链接发生更改,面包屑路径为:

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

MSDN Library > .NET开发> .NET Framework 4.6 和 4.5 >开发指南》数据和建模> XML 标准参考 > XML 模式 (XSD) 参考 > XML 架构元素 >元素

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:

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:

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

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

杯别 2024-10-15 19:24:50

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

RE 你的代码:

我自己才刚刚开始涉足密钥,但我想我在你的代码中发现了一个错误 - aKey 应该看起来像:

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

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

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.

RE your code:

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

<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 selector xpath 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.

谈场末日恋爱 2024-10-15 19:24:50

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

有关更多信息,请参阅:

更新

我希望得到答案中包含的示例,但在休假之前我已经没有时间了。下面是我们设计文档中的一个示例,演示了这一概念:

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.

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:

无言温柔 2024-10-15 19:24:50

请尝试查看此key/keyref 教程

彩色文本非常有帮助。

Please, try to see this key/keyref tutorial.

The colored text is very helpful.

巷雨优美回忆 2024-10-15 19:24:50

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

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

对于您的示例 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>

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

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

使用 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>

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

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

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

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

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

<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:ID type 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.

By default, an element or attribute of type xs:IDREF binds 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).

Example using JAXB schema annotations (not tested):

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文