How to control references between elements in XML -


in previous question (how create references between elements in xml) asked how create, in xml schema, references between elements.

ok, noticed something. example, defining these 3 types of vehicles:

<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> 

... can define complex vehicle, example:

<trailertruck id="tt1">     <car refid="car1"/>     <trailer refid="trailer1"/> </trailertruck>  <trailertruck id="tt2">     <truck refid="truck1"/>     <trailer refid="trailer1"/> </trailertruck> 

okay, works, noticed - unfortunately - allowed such thing:

<trailertruck id="tt3_wrong">     <truck refid="trailer1"/>   <!-- element "truck" should not     refer trailer!! should able refer truck1 -->     <trailer refid="car1"/>     <!-- before, element trailer     should able refer trailer1 --> </trailertruck>  <trailertruck id="tt4_wrong">     <car refid="truck1"/>       <!-- element **car** should not     refer truck !! -->     <trailer refid="trailer1"/> </trailertruck> 

so, if put incorrect references, not shown error. instead, notified. want insert kind of restriction or control. how?


now show current implementation.

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 , 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> 

i think you're looking referential integrity; need xsd:key/xsd:keyref. id/idref in xsd spec backward compatibility dtds; wouldn't use them in xsds.

this modified xsd:

<?xml version="1.0" encoding="utf-8" ?> <!-- xml schema generated 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 , 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> 

with key/keyref, control cross checks. diagram below shows content expanded demonstrate:

  • cars , trailers pk
  • how link trailer trucks trailers
  • how link driving part (a car in case) associated counterpart (a car in top section of xml).

enter image description here

it consistent referential integrity in "traditional" database design: got primary keys, foreign keys. posted xml invalid; 1 below valid version of it.

<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> 

Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -