长话短说:我想知道如何使用XSD中的key / keyref让元素互相引用。它必须有一个示例的形式,使用简单的xsd和XML。
长篇小说:我熟悉ID / IDREF的用法。我用它来连接JAXB的元素。我一再被告知,XSD中的key / keyref构造为元素间引用提供了增强的灵活性。我已经咨询了OReilly XML Schema book,它似乎教会了关于key / keyref的正确定义以及它与ID / IDREF(但更好)类似的一切,并没有给出一个简单的使用示例。它似乎并不相似,因为您将ID定义为一个元素中的属性,将IDREF定义为另一个元素中的ID。但是key / keyref必须在引用和引用元素(AFAIK)的共同祖先中定义......
我使用XSD文件生成带有XJC的JAXB绑定Java类
我已经搜索过how-tos,教程和示例,但谷歌给了我一些废话。同样适用于搜索SO(也使用谷歌和包含搜索的'+')。
为了让每个人的生活更轻松,我已经准备了一个已经定义的密钥/密钥对的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>
一段XML如何看起来像一个'owner'元素引用'referenced'-element?
编辑:应用了Tom W提议的更改,将关键元素的xpath属性更改为“owner”。 JAXB(XJC)仍然不在乎。
谢谢
答案 0 :(得分:6)
实例文档中没有特殊语法。简单地要求keyref节点匹配现存的密钥节点。验证将告诉您是否满足关键约束。
重新编写代码:
我自己刚开始涉足钥匙,但我想我发现了你的错误 - aKey
应该是这样的:
<xs:key name="aKey">
<xs:selector xpath="owner" />
<xs:field xpath="@id" />
</xs:key>
此外 - 这是一个问题 - 关键限制无法识别默认命名空间。您必须始终在selector
xpath的每个部分前加上您正在查找的元素的名称空间前缀。如果你没有命名空间前缀 - 很难,你需要添加一个。这是标准的限制。
答案 1 :(得分:5)
JAXB规范未明确涵盖key / keyref。然而,EclipseLink MOXy(我是技术主管)等JAXB实现对此有扩展。我们即将推出的2.2版本提供了一种通过注释指定这种关系的方法(我将把一个例子放在一起)。以下是使用当前版本如何完成的链接。
有关详细信息,请参阅:
<强>更新强>
我希望得到答案中的一个例子,但在我休假之前,我的时间已经不多了。以下是我们的设计文档中的一个示例,它演示了这个概念:
答案 2 :(得分:4)
我发现这个线程正在搜索OP正在搜索的相同内容 - 一个<xs:key>
元素的简单用法示例。所有JAXB的东西对我来说都是希腊人,而且让人分心。对于其他人稍后发现这个帖子,这是一个简单的例子,在OP提出问题后几年就在MSDN上发布了:
https://msdn.microsoft.com/en-us/library/ms256101%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
如果MSDN链接发生更改,则痕迹路径为:
https://msdn.microsoft.com/library然后点击“切换到图书馆TOC视图”, 并向下钻取:
MSDN Library&gt; .NET开发&gt; .NET Framework 4.6和4.5&gt;开发指南&gt;数据和建模&gt; XML标准参考&gt; XML Schemas(XSD)参考&gt; XML模式元素&gt; &LT; XSD:密钥GT;元件
答案 3 :(得分:3)
JAXB不支持xs:key
或xs:keyref
的引用。规范声明可以在验证期间检查这些约束,但它们对数据没有影响。
但是,您可以使用xs:ID
和xs:IDREF
来实现此目标(或多或少)。有关介绍,请参阅Wolfgang Laun在J 2.2.15 Referring to Another XML Element中的章节4.3 Assembling Data with Links (ID, IDREF)和AXB Tutorial。
对于您的示例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>
答案 4 :(得分:3)
请尝试查看此key/keyref tutorial。
彩色文字非常有用。