XSD架构参考完整性xs:keyref

时间:2012-08-09 16:13:40

标签: xml xsd constraints unique keyref

我有一个名为Event的xsd,它包含两个类型为AccountStructureItem和EventItem的列表(“AccountStructures”和“Events”)。有一个属性:AccountStructureItem中的SourceId定义为unique和key。 EventItem类型还有一个SourceId属性,它是对AccountStructureItem的SourceId的引用。

我将AccountStructureItem的id声明如下:

<xs:unique name="accounts_unique">
<xs:selector xpath="AccountStructureItem"/>
<xs:field xpath="SourceId"/>
</xs:unique>

<xs:key name="accounts_key">
<xs:selector xpath="AccountStructureItem"/>
<xs:field xpath="SourceId"/>
</xs:key>

关系是一对多,可以有许多EventItem引用相同的AccountStructureItem的SourceId。因此EventItem的关键是另一个属性。

我的问题:尝试使用xs:keyref创建对帐户结构的accounts_key的密钥引用约束时出错。

<xs:keyref name="events_constraint" refer="accounts_key">
<xs:selector xpath="AccountStructureItem"/>
<xs:field xpath="SourceId"/>
</xs:keyref>

验证后面的错误消息如下:“keyref事件无法在范围内找到引用的密钥或唯一”

请参阅下面提供的完整XSD和测试xml文件:

<!-- XSD -->

<xs:element name="Event">
    <xs:complexType>
      <xs:sequence>
        <!--Information Start-->
        <xs:element minOccurs="1" maxOccurs="1" nillable="false" name="Information" type="ct:Information" />
        <!--Information End-->

        <!--AccountStructure Start-->
        <xs:element name="AccountStructures">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" name="AccountStructureItem">
                <xs:complexType>
                  <xs:complexContent mixed="false">
                    <xs:extension base="ct:AccountStructureItem" />
                  </xs:complexContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>

          <xs:unique name="accounts_unique">
            <xs:selector xpath="AccountStructureItem"/>
            <xs:field xpath="SourceId"/>
          </xs:unique>

          <xs:key name="accounts_key" id="accounts_key_id">
            <xs:selector xpath="AccountStructureItem"/>
            <xs:field xpath="SourceId"/>
          </xs:key>

        </xs:element>
        <!--AccountStructure End-->

        <!--Events Start-->
        <xs:element name="Events" minOccurs="1" maxOccurs="1" nillable="false">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="EventItem" minOccurs="1" maxOccurs="10000">
                <xs:complexType>
                  <xs:complexContent mixed="false">
                    <xs:extension base="ct:EventItem" />
                  </xs:complexContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>

          <xs:unique name="events_unique">
            <xs:selector xpath="EventItem"/>
            <xs:field xpath="SourceEventId"/> <!-- events has a different key -->
          </xs:unique>

          <xs:key name="events_key">
            <xs:selector xpath="EventItem"/>
            <xs:field xpath="SourceEventId"/> <!-- events has a different key -->
          </xs:key>

          <xs:keyref name="events_constraint" refer="accounts_key">
            <xs:selector xpath="AccountStructureItem"/>
            <xs:field xpath="SourceId"/>
          </xs:keyref>

        </xs:element>
        <!--Events End-->
      </xs:sequence>
    </xs:complexType>
  </xs:element>


<!-- XML -->

<AccountStructures>

    <AccountStructureItem>
      <SourceId>AC1</SourceId>
      <AccountStructureType>Site</AccountStructureType>
      <ParentSourceId>000017252</ParentSourceId>
      <Name>Oras Isometsän tehdas</Name>
      <Street>Isometsäntie 2</Street>
      <City>RAUMA</City>
    </AccountStructureItem>

    <AccountStructureItem>
      <SourceId>AC2</SourceId>
      <AccountStructureType>Site</AccountStructureType>
      <ParentSourceId>000017252</ParentSourceId>
      <Name>Oras Oy lomamökki</Name>
      <Street>Lomapolku 15</Street>
      <City>RAUMA</City>
    </AccountStructureItem>


  </AccountStructures>

  <Events>

    <EventItem>
      <SourceId>AC1</SourceId>
      <AccountStructureType>SiteLocation</AccountStructureType>
      <SourceEventId>123</SourceEventId>
      <EventDate>2012-06-20T17:57:26</EventDate>
      <EventText>
        <EnglishValue> Oras/Isometsän tehdas Oras Isometsä  </EnglishValue>
        <LocalValue> Oras/Isometsän tehdas Oras Isometsä  </LocalValue>
      </EventText>
      <Objects>
        <Object>
          <EnglishValue>Location</EnglishValue>
          <LocalValue>Location</LocalValue>
        </Object>
      </Objects>
      <Type>
        <EnglishValue>Round</EnglishValue>
        <LocalValue>Round</LocalValue>
      </Type>
      <Solutions>
        <Solution>
          <EnglishValue>On-site</EnglishValue>
          <LocalValue>On-site</LocalValue>
        </Solution>
      </Solutions>
      <EventValue>
        <UnitType>Integer</UnitType>
        <Value>1</Value>
      </EventValue>
      <Notes></Notes>
    </EventItem>

    <EventItem>
      <SourceId>AC1</SourceId>
      <AccountStructureType>SiteLocation</AccountStructureType>
      <SourceEventId>1234</SourceEventId>
      <EventDate>2012-06-20T17:57:26</EventDate>
      <EventText>
        <EnglishValue> Oras/Isometsän tehdas Oras Isometsä  </EnglishValue>
        <LocalValue> Oras/Isometsän tehdas Oras Isometsä  </LocalValue>
      </EventText>
      <Objects>
        <Object>
          <EnglishValue>Location</EnglishValue>
          <LocalValue>Location</LocalValue>
        </Object>
      </Objects>
      <Type>
        <EnglishValue>Round</EnglishValue>
        <LocalValue>Round</LocalValue>
      </Type>
      <Solutions>
        <Solution>
          <EnglishValue>On-site</EnglishValue>
          <LocalValue>On-site</LocalValue>
        </Solution>
      </Solutions>
      <EventValue>
        <UnitType>Integer</UnitType>
        <Value>1</Value>
      </EventValue>
      <Notes></Notes>
    </EventItem>
  </Events>

1 个答案:

答案 0 :(得分:3)

我自己得到了解决方案。问题是我在元素列表中声明了键和引用。我现在在两个列表之外移动了key,unique和ref的声明,并使用“list / item”xpath来访问它们。像这样:

  <xs:selector xpath="AccountStructures/AccountStructureItem"/>
  <xs:field xpath="SourceId"/>
</xs:unique>

<xs:key name="accounts_key" id="accounts_key_id">
  <xs:selector xpath="AccountStructures/AccountStructureItem"/>
  <xs:field xpath="SourceId"/>
</xs:key>

<xs:unique name="events_unique">
  <xs:selector xpath="Events/EventItem"/>
  <xs:field xpath="SourceEventId"/>
</xs:unique>

<xs:key name="events_key">
  <xs:selector xpath="Events/EventItem"/>
  <xs:field xpath="SourceEventId"/>
</xs:key>

<xs:keyref name="events_constraint" refer="accounts_key">
  <xs:selector xpath="Events/EventItem"/>
  <xs:field xpath="SourceId"/>
</xs:keyref>