元素出现在指定的数字

时间:2011-05-07 15:55:40

标签: xml xsd

这是我的xml文档

<root>
 <num>3</num>
 <a>
  <b>
   <c n="m"></c>
   <c></c>
   <c n="e"></c>
  </b>
  <b>
   <c n="s"></c>
   <c n="w"></c>
   <c></c>
  </b>
  <b>
   <c n="q"></c>
   <c></c>
   <c n="u"></c>
  </b>
 </a>
</root>

我想创建一个xml Schema b中的元素c必须只出现n次。(n在num元素中)
我认为它使用key,keyref或unique。

1 个答案:

答案 0 :(得分:0)

这是不可能的。

Key,keyref和unique将无济于事。唯一将确保您没有重复的项目。 key和keyref将确保B中的元素与A中的元素匹配。

maxOccurs限制需要一个简单的整数参数。任何类型的Xpath表达式都无法计算整数。见这里:http://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints

<强>更新

如果要使用unique,key和key ref解决问题,则必须在属性中创建数字索引。下图说明了架构:

enter image description here

您必须向引用主属性索引的c节点添加属性。在此示例中,它存储在多个num元素中。您可以在/root/num@count上设置整数限制,唯一和键约束。之后,您可以创建从/root/a/b/c@count/root/num@count的参考约束。这将创建一个最大约束。您可以拥有与c个节点一样多的num个节点,但您也可以拥有更少的节点。

这是架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:element name="root">
    <xs:annotation>
      <xs:documentation>Comment describing your root element</xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element name="num" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute name="count" type="xs:unsignedInt" use="required"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="a" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="b" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="c" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:attribute name="count" type="xs:integer" use="required"/>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="num_unique">
      <xs:selector xpath="num"/>
      <xs:field xpath="@count"/>
    </xs:unique>
    <xs:key name="num_key">
      <xs:selector xpath="num"/>
      <xs:field xpath="@count"/>
    </xs:key>
    <xs:keyref name="num_ref" refer="num_key">
      <xs:selector xpath="a/b/c"/>
      <xs:field xpath="@count"/>
    </xs:keyref>
  </xs:element>
</xs:schema>

这将是一个有效的文件:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="root.xsd">
  <num count="1"/>
  <num count="2"/>
  <num count="3"/>
  <a>
    <b>
      <c count="1"/>
    </b>
    <b>
      <c count="1"/>
      <c count="2"/>
    </b>
  </a>
</root>

如果添加<c count="4"/>,它将无效。现在我不知道如何使它成为身份参考。也许有可能扭转参考方向......

但是,将约束放入与数据本身相同的文件中并不是一件好事。如果您不信任您的数据源,那么请求您的数据没有多大意义自我约束的来源。您必须将约束放入模式或通过某种程序逻辑扩展验证。例如,您可以计算其父节点中所有c个节点的数量,并检查它们是否全部相同或者是否都等于给定数量。这将更有意义,因为这是实施约束的唯一安全方式。