在XSD架构中,如何区分不同类型的IDREF

时间:2012-11-26 12:44:24

标签: xml xsd

我有一个与此类似的XML结构:

<root>
   <hierarchy1>
       <foo id="foo1" /> <!-- id is of type id -->
       <bar id="bar1" /> <!-- id is of type id -->
   </hierarchy1>
   <hierarchy2>
       <foohandler ref="foo1" /> <!-- ref is of type idref -->
       <barhandler ref="bar1" /> <!-- ref is of type idref -->
   </hierarchy2>
</root>

即。我有不同类型的具有ID的对象,我有不同类型的目标对象需要使用IDREF引用这些ID。

有没有办法确保IDREF具有正确的预期类型,即

  • <foohandler ref="foo1" />有效,而
  • <foohandler ref="bar1" />不是吗?

2 个答案:

答案 0 :(得分:2)

使用xs:key / xs:keyref而不是ID / IDREF。我会告诉你查看细节;如果你遇到困难再问一次。

答案 1 :(得分:1)

我几乎发布了一个使用基于模式的限制( foo [0-9] + 等)的答案来实现OP所要求的。但是在发布之前我发现了 keys keyrefs ,这似乎是解决方案。所以我想出了以下架构;但是,起初由于愚蠢的名称空间声明问题而无法正常工作。我主要发布它,因为我之前不知道如何做到这一点而且我疯了,因为我知道我几乎就在那里

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns="http://stackoverflow.com"
           xmlns:so="http://stackoverflow.com"
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://stackoverflow.com"
           attributeFormDefault="qualified"
           elementFormDefault="qualified">
  <xs:element name="root" type="rootType">
    <xs:key name="fooKey">
      <xs:selector xpath="so:hierarchy1/so:foo"/>
      <xs:field xpath="@so:key"/>
    </xs:key>
    <xs:key name="barKey">
      <xs:selector xpath="so:hierarchy1/so:bar"/>
      <xs:field xpath="@so:key"/>
    </xs:key>
    <xs:keyref name="fooKeyref" refer="fooKey">
      <xs:selector xpath="so:hierarchy2/so:foohandler"/>
      <xs:field xpath="@so:keyref"/>
    </xs:keyref>
    <xs:keyref name="barKeyref" refer="barKey">
      <xs:selector xpath="so:hierarchy2/so:barhandler"/>
      <xs:field xpath="@so:keyref"/>
    </xs:keyref>
  </xs:element>

  <xs:complexType name="rootType">
    <xs:sequence>
      <xs:element name="hierarchy1" type="hierarchy1Type"/>
      <xs:element name="hierarchy2" type="hierarchy2Type"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="hierarchy1Type">
    <xs:sequence>
      <xs:element name="foo" type="fooType"/>
      <xs:element name="bar" type="barType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="hierarchy2Type">
    <xs:sequence>
      <xs:element name="foohandler" type="foohandlerType"/>
      <xs:element name="barhandler" type="barhandlerType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="fooType">
    <xs:attribute name="key" type="xs:integer"/>
  </xs:complexType>

  <xs:complexType name="barType">
    <xs:attribute name="key" type="xs:integer"/>
  </xs:complexType>

  <xs:complexType name="foohandlerType">
    <xs:attribute name="keyref" type="xs:integer"/>
  </xs:complexType>

  <xs:complexType name="barhandlerType">
    <xs:attribute name="keyref" type="xs:integer"/>
  </xs:complexType>
</xs:schema>

上面的模式验证了下面的XML文档。

<?xml version="1.0" encoding="UTF-8"?>
<so:root xmlns:so="http://stackoverflow.com"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://stackoverflow.com a.xsd">
  <so:hierarchy1>
    <so:foo so:key="1"/>
    <so:bar so:key="2"/>
  </so:hierarchy1>
  <so:hierarchy2>
    <so:foohandler so:keyref="1"/>
    <so:barhandler so:keyref="2"/>
  </so:hierarchy2>
</so:root>

如果<so:barhandler so:keyref="2"/>更改为<so:barhandler so:keyref="1"/><so:barhandler so:keyref="3"/>,则该文档无效。

这里的问题是,如果没有指定名称空间xmlns:so="http://stackoverflow.com"并在xpathxs:selector的{​​{1}}属性中使用相同的名称,一些解析器将不关心文件的完整性。

Eclipse的XML解析器/验证器和this online tool没有给出关于我的密钥 keyref 声明的废话,直到我指定XPath表达式引用哪个命名空间

底层石灰可以使用命名空间everyhwere

This answer lead me to my relevation.