2

我有一个类似于这样的 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" />不是吗?
4

2 回答 2

2

使用 xs:key/xs:keyref 代替 ID/IDREF。我会让你去查细节;再次询问您是否卡住了。

于 2012-11-26T18:52:57.290 回答
2

我几乎发布了一个答案,它使用基于模式的限制(foo[0-9]+等)来实现 OP 的要求。但是,在发布之前,我发现了keyskeyrefs,这似乎是解决方案。所以我想出了以下架构;但是,起初它没有工作,因为一个愚蠢的命名空间声明问题。我主要发布它,因为我之前也不知道该怎么做,而且我快疯了,因为我知道我快到了

<?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:selectorxs:field

Eclipse 的 XML 解析器/验证器和这个在线工具在我指定 XPath 表达式应该引用哪个命名空间之前,并没有对我的keykeyref声明给出废话。

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

这个答案将我引向我的关联。

于 2012-11-27T07:56:34.653 回答