[英]XML Schema key/keyref - how to use them?
长话短说:我想知道如何使用XSD中的key / keyref让元素互相引用。 它必须有一个示例的形式,使用简单的xsd和XML。
长话:我熟悉ID / IDREF的用法。 我用它来连接JAXB的元素。 我一再被告知,XSD中的key / keyref构造为元素间引用提供了增强的灵活性。 我已经查阅了OReilly XML Schema书 ,它似乎教授了关于key / keyref的正确定义以及它与ID / IDREF(但更好)类似的一切,并没有给出一个简单的使用示例。 它似乎并不相似,因为您将ID定义为一个元素中的属性,将IDREF定义为另一个元素中的ID。 但是key / keyref必须在引用和引用元素(AFAIK)的共同祖先中定义...
我使用XSD文件使用XJC生成JAXB绑定的Java类
我搜索了how-to,教程和示例,但谷歌给了我一些废话。 同样适用于搜索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'元素引用'引用'元素?
编辑:应用Tom W提议的更改,将关键元素的xpath属性更改为“owner”。 JAXB(XJC)仍然不在乎。
谢谢
实例文档中没有特殊语法。 简单地要求keyref节点匹配现存的密钥节点。 验证将告诉您是否满足关键约束。
你的代码:
我自己刚刚开始涉足钥匙,但我想我发现了你的错误 - aKey
应该是这样的:
<xs:key name="aKey">
<xs:selector xpath="owner" />
<xs:field xpath="@id" />
</xs:key>
此外 - 这是一个问题 - 关键限制无法识别默认命名空间。 您必须始终在selector
xpath的每个部分前面添加您正在查找的元素的名称空间前缀。 如果你没有命名空间前缀 - 很难,你需要添加一个。 这是标准的限制。
我发现这个线程正在搜索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> .NET开发> .NET Framework 4.6和4.5>开发指南>数据和建模> XML标准参考> XML模式(XSD)参考> XML模式元素> <xsd:key>元素
JAXB规范没有明确涵盖key / keyref。 但是, EclipseLink MOXy (我是技术主管)等JAXB实现对此有扩展。 我们即将推出的2.2版本提供了一种通过注释指定这种关系的方法(我将把一个例子放在一起)。 以下是使用当前版本如何完成的链接。
有关更多信息,请参阅
UPDATE
我希望得到答案的一个例子,但在我休假之前,我的时间已经不多了。 以下是我们的设计文档中的示例,它演示了以下概念:
请尝试查看此密钥/ keyref教程 。
彩色文字非常有用。
JAXB不支持通过xs:key
或xs:keyref
。 规范声明可以在验证期间检查这些约束,但它们对数据没有影响。
但是,您可以使用xs:ID
和xs:IDREF
来实现此目的(或多或少)。 有关介绍,请参阅Wolfgang Laun的J AXB教程中的章节2.2.15参考另一个XML元素和4.3使用链接组装数据(ID,IDREF) 。
对于您的示例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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.