2015-04-01 2 views
6

В моем предыдущем вопросе (How create references between elements in XML) Я спросил, как создавать в XML-схеме ссылки между элементами.Как управлять ссылками между элементами в XML

Хорошо, но теперь я кое-что заметил. Например, определение этих трех типов транспортных средств:

<Car id="car1"> 
    <plate>AAA</plate> 
    <mark>Peugeot</mark> 
    <model>206</model> 
</Car> 

<Truck id="truck1"> 
    <plate>BBB</plate> 
    <mark>Scania</mark> 
    <model>X1</model> 
</Truck> 

<Trailer id="trailer1"> 
    <plate>CCC</plate> 
    <mark>Scania</mark> 
    <model>T1</model> 
</Trailer> 

... Теперь я могу определить сложное транспортное средство, например:

<TrailerTruck id="tt1"> 
    <Car refid="car1"/> 
    <Trailer refid="trailer1"/> 
</TrailerTruck> 

<TrailerTruck id="tt2"> 
    <Truck refid="truck1"/> 
    <Trailer refid="trailer1"/> 
</TrailerTruck> 

Хорошо, это работает, но я заметил, что - к сожалению, - также допускается такая вещь:

<TrailerTruck id="tt3_WRONG"> 
    <Truck refid="trailer1"/> <!-- an element "Truck" should not 
    refer to a trailer!! Should be able to refer only to truck1 --> 
    <Trailer refid="car1"/>  <!-- like before, an element Trailer 
    should be able to refer only trailer1 --> 
</TrailerTruck> 

<TrailerTruck id="tt4_WRONG"> 
    <Car refid="truck1"/>  <!-- an element **Car** should not 
    refer to a Truck !! --> 
    <Trailer refid="trailer1"/> 
</TrailerTruck> 

Так что, если я помещаю неправильные ссылки, не отображается никаких ошибок. Вместо этого я хотел бы получить уведомление. Я хочу вставить какое-то ограничение или контроль. Но как?


Теперь я покажу вам свою текущую реализацию.

VehicleXMLSchema.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="Fleet" type="FleetType"/> 


    <xs:complexType name="FleetType"> 
     <xs:choice maxOccurs="unbounded"> 
      <xs:element ref="Car" /> 
      <xs:element ref="Truck" /> 
      <xs:element ref="Trailer" /> 
      <xs:element ref="TrailerTruck" /> 
     </xs:choice> 
    </xs:complexType> 


    <xs:complexType name="VehicleType" abstract="true"> 
     <xs:sequence minOccurs="0"> 
      <xs:element name="plate" type="xs:string" minOccurs="1" /> 
      <xs:element name="mark" type="xs:string" minOccurs="1" /> 
      <xs:element name="model" type="xs:string" minOccurs="1" /> 
     </xs:sequence> 
    </xs:complexType> 




    <!-- SimpleVehicle and ComplexVehicle --> 

    <xs:complexType name="SimpleVehicle"> 
     <xs:complexContent> 
      <xs:extension base="VehicleType"> 
       <xs:attribute name="id" type="xs:ID"/> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="ComplexVehicle"> 
     <xs:complexContent> 
      <xs:extension base="VehicleType"> 
       <xs:attribute name="refid" type="xs:IDREF"/> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 




    <!-- Car, Truck, Trailer --> 

    <xs:element name="Car" type="SimpleVehicle" /> 
    <xs:element name="Truck" type="SimpleVehicle"/> 
    <xs:element name="Trailer" type="SimpleVehicle"/> 




    <!-- TrailerTruck --> 

    <xs:group name="DrivingPart"> 
     <xs:choice> 
      <xs:element name="Car" type="ComplexVehicle" /> 
      <xs:element name="Van" type="ComplexVehicle"/> 
      <xs:element name="Truck" type="ComplexVehicle"/> 
     </xs:choice> 
    </xs:group> 

    <xs:element name="TrailerTruck"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:group ref="DrivingPart" minOccurs="1" maxOccurs="1"/> 
       <xs:element name="Trailer" type="ComplexVehicle" minOccurs="1" maxOccurs="1"/> 
      </xs:sequence> 
      <xs:attribute name="id" type="xs:ID"/> 
     </xs:complexType> 
    </xs:element> 

</xs:schema> 

Shipper1.xml:

<Fleet shipperName="Shipper1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="VehicleXMLSchema.xsd"> 

    <Car id="car1"> 
     <plate>AAA</plate> 
     <mark>Peugeot</mark> 
     <model>206</model> 
    </Car> 

    <Truck id="truck1"> 
     <plate>DDD</plate> 
     <mark>Scania</mark> 
     <model></model> 
    </Truck> 

    <Trailer id="trailer1"> 
     <plate>EEE</plate> 
     <mark>Scania</mark> 
     <model></model> 
    </Trailer> 


    <TrailerTruck id="trailerTruck1"> 
     <Car refid="car1" /> 
     <Trailer refid="trailer1" /> 
    </TrailerTruck> 

    <TrailerTruck id="trailerTruck2_WRONG"> 
     <Truck refid="car1" /> 
     <Trailer refid="trailer1" /> 
    </TrailerTruck> 

    <TrailerTruck id="trailerTruck3_WRONG"> 
     <Truck refid="truck1" /> 
     <Trailer refid="car1" /> 
    </TrailerTruck> 

</Fleet> 
+0

@sergioFC Я использую Eclipse IDE. Я думаю, что поддерживается. – Gioce90

ответ

6

Я думаю, что вы ищете ссылочной целостности; вам действительно нужно xsd:key/xsd:keyref. ID/IDREF находятся в спецификации XSD для обратной совместимости с DTD; Я бы не использовал их в XSD.

Это ваш модифицированный XSD:

<?xml version="1.0" encoding="utf-8" ?> 
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) --> 
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Fleet" type="FleetType"> 
     <xs:key name="PK_Cars"> 
      <xs:selector xpath="Car"/> 
      <xs:field xpath="@id"/> 
     </xs:key> 
     <xs:key name="PK_Trucks"> 
      <xs:selector xpath="Truck"/> 
      <xs:field xpath="@id"/> 
     </xs:key> 
     <xs:key name="PK_Trailers"> 
      <xs:selector xpath="Trailer"/> 
      <xs:field xpath="@id"/> 
     </xs:key> 
     <xs:key name="PK_TrailerTruck"> 
      <xs:selector xpath="TrailerTruck"/> 
      <xs:field xpath="@id"/> 
     </xs:key> 
     <xs:keyref name="FK_TrailerTruck2Trailers" refer="PK_Trailers"> 
      <xs:selector xpath="TrailerTruck/Trailer"/> 
      <xs:field xpath="@refid"/> 
     </xs:keyref> 
     <xs:keyref name="FK_TrailerTruck2Cars" refer="PK_Cars"> 
      <xs:selector xpath="TrailerTruck/Car"/> 
      <xs:field xpath="@refid"/> 
     </xs:keyref> 
     <xs:keyref name="FK_TrailerTruck2Trucks" refer="PK_Trucks"> 
      <xs:selector xpath="TrailerTruck/Truck"/> 
      <xs:field xpath="@refid"/> 
     </xs:keyref> 
    </xs:element> 
    <xs:complexType name="FleetType"> 
     <xs:choice maxOccurs="unbounded"> 
      <xs:element ref="Car"/> 
      <xs:element ref="Truck"/> 
      <xs:element ref="Trailer"/> 
      <xs:element ref="TrailerTruck"/> 
     </xs:choice> 
     <xs:attribute name="shipperName" type="xs:string"/> 
    </xs:complexType> 

    <xs:complexType name="VehicleType" abstract="true"> 
     <xs:sequence minOccurs="0"> 
      <xs:element name="plate" type="xs:string" minOccurs="1"/> 
      <xs:element name="mark" type="xs:string" minOccurs="1"/> 
      <xs:element name="model" type="xs:string" minOccurs="1"/> 
     </xs:sequence> 
    </xs:complexType> 
    <!-- SimpleVehicle and ComplexVehicle --> 
    <xs:complexType name="SimpleVehicle"> 
     <xs:complexContent> 
      <xs:extension base="VehicleType"> 
       <xs:attribute name="id" type="xs:ID"/> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="ComplexVehicle"> 
     <xs:complexContent> 
      <xs:extension base="VehicleType"> 
       <xs:attribute name="refid" type="xs:IDREF"/> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    <!-- Car, Truck, Trailer --> 
    <xs:element name="Car" type="SimpleVehicle"/> 
    <xs:element name="Truck" type="SimpleVehicle"/> 
    <xs:element name="Trailer" type="SimpleVehicle"/> 
    <!-- TrailerTruck --> 
    <xs:group name="DrivingPart"> 
     <xs:choice> 
      <xs:element name="Car" type="ComplexVehicle"/> 
<!--   <xs:element name="Van" type="ComplexVehicle"/>--> 
      <xs:element name="Truck" type="ComplexVehicle"/> 
     </xs:choice> 
    </xs:group> 
    <xs:element name="TrailerTruck"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:group ref="DrivingPart" minOccurs="1" maxOccurs="1"/> 
       <xs:element name="Trailer" type="ComplexVehicle" minOccurs="1" maxOccurs="1"/> 
      </xs:sequence> 
      <xs:attribute name="id" type="xs:ID"/> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

С ключом/KeyRef, теперь контролировать перекрестные проверки. Приведенная ниже диаграмма показывает только содержание расширена, чтобы показать:

  • автомобилей и прицепов PK
  • как вы связываете трейлер грузовики прицепы
  • как связать вождения часть (автомобиль, в данном случае) с соответствующим коллегой (автомобиль в верхней части вашего XML).

enter image description here

Это согласуется с ссылочной целостности в «традиционном» проектирования баз данных: вы получили ваши первичные ключи, внешние ключи. Ваш опубликованный XML теперь будет недействительным; один из них будет действительной версией.

<Fleet shipperName="Shipper1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="VehicleXMLSchema.xsd"> 

    <Car id="car1"> 
     <plate>AAA</plate> 
     <mark>Peugeot</mark> 
     <model>206</model> 
    </Car> 

    <Truck id="truck1"> 
     <plate>DDD</plate> 
     <mark>Scania</mark> 
     <model></model> 
    </Truck> 

    <Trailer id="trailer1"> 
     <plate>EEE</plate> 
     <mark>Scania</mark> 
     <model></model> 
    </Trailer> 

    <TrailerTruck id="trailerTruck1"> 
     <Car refid="car1"/> 
     <Trailer refid="trailer1"/> 
    </TrailerTruck> 

    <TrailerTruck id="trailerTruck2_WRONG"> 
     <Truck refid="truck1"/> 
     <Trailer refid="trailer1"/> 
    </TrailerTruck> 

    <TrailerTruck id="trailerTruck3_WRONG"> 
     <Truck refid="truck1"/> 
     <Trailer refid="trailer1"/> 
    </TrailerTruck> 

</Fleet> 
+0

это кажется хорошим ... но не лучше создать один ключ и refkey? Как .. bla bla .. ?? – Gioce90

+1

С помощью одного ключа вы вернетесь к ограничениям ID/IDREF; вы попросили «элемент« Грузовик »не должен ссылаться на трейлер! Должен иметь возможность ссылаться только на грузовик1» и т. д .; поэтому вам нужно различать идентификаторы и их ссылки, следовательно, пары PK/FK. Я надеялся, что вы знакомы с ER-моделированием, и это то, что соответствует key/keyref.При этом, если вы можете достичь того, что вам нужно с помощью одного ключа, тогда, конечно, сделайте это. –

Смежные вопросы