Sto provando a definire alcuni vincoli di chiave esterna su uno schema XML utilizzando xs: key e xs: definizioni keyref. Voglio la struttura del documento di essere gerarchico nel seguente modo:XSD key/keyref: struttura chiave gerarchica
<?xml version="1.0" encoding="UTF-8"?>
<tns:root xmlns:tns="http://www.example.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/ SampleSchema.xsd ">
<parent parentKey="parent1">
<child childKey="child1"/>
<child childKey="child2"/>
</parent>
<parent parentKey="parent2">
<child childKey="child1"/>
<child childKey="child2"/>
</parent>
<referrer parentRef="parent1" childRef="child2"/>
</tns:root>
A ciascun genitore ha una chiave univoca (a livello mondiale), definito da parentKey. Ogni bambino ha una chiave definita da childKey, ma childKey è solo univoco nell'ambito di parentela contenente.
Esiste quindi un elenco di referenti con riferimenti a chiave esterna a un particolare genitore e figlio.
Sono in grado di definire i tasti come voglio, semplicemente inserendoli sull'elemento corretto: il vincolo parentKey sull'elemento radice e il vincolo childKey sull'elemento padre. Posso anche definire il keyref di parentKey senza difficoltà.
I problemi sorgono quando si tenta di definire un keyref per childKey. Ho provato a definire un keyref semplice sull'elemento root su childKey, ma ciò non funziona poiché non vedo alcun modo per selezionare solo gli elementi figlio sotto il sottoalbero genitore appropriato. (Il validatore di Eclipse, almeno, convalida sempre semplicemente il contenuto dello albero secondario genitore nel documento ...).
poi ho provato definente una chiave composta (su root), con:
- selettore = genitore
- campo = @parentKey
- campo = bambino/@ ChildKey
Questo fallisce se c'è più di un figlio definito sotto il genitore. Questo è il comportamento corretto basato su XSD 1.1 spec, sezione 3.11.4, elemento 3, in cui si afferma che la chiave deve corrispondere al massimo a un nodo per ogni definizione di campo.
Giusto per ribadire: se impongo che childKeys sia globalmente unico, è facile da implementare; la difficoltà è intorno al riferimento localmente childKeys unici.
Qualsiasi maestro XSD là fuori ha un'idea?
Per riferimento, ecco un XSD di esempio, con una non riuscita ChildKey keyref commentato out:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/" xmlns:tns="http://www.example.org/" elementFormDefault="unqualified">
<element name="root">
<complexType>
<sequence>
<element name="parent" maxOccurs="unbounded" minOccurs="1">
<complexType>
<sequence>
<element name="child" maxOccurs="unbounded" minOccurs="1">
<complexType>
<attribute name="childKey" type="string" use="required"/>
</complexType>
</element>
</sequence>
<attribute name="parentKey" type="string" use="required"/>
</complexType>
<key name="childKeyDef">
<selector xpath="child"/>
<field xpath="@childKey"/>
</key>
</element>
<element name="referrer" maxOccurs="unbounded" minOccurs="1">
<complexType>
<attribute name="parentRef" type="string"/>
<attribute name="childRef" type="string"/>
</complexType>
</element>
</sequence>
</complexType>
<key name="parentKeyDef">
<selector xpath="parent"/>
<field xpath="@parentKey"/>
</key>
<keyref name="parentKeyRef" refer="tns:parentKeyDef">
<selector xpath="referrers"/>
<field xpath="@parentRef"/>
</keyref>
<!-- <keyref name="childKeyRef" refer="tns:childKeyDef">-->
<!-- <selector xpath="referrers"/>-->
<!-- <field xpath="@childRef"/>-->
<!-- </keyref>-->
</element>
</schema>
Hi Aron, hai trovato una soluzione per questo problema? Sono anche bloccato con un problema simile. (Non posso cambiare il mio xml). – Rahul
Ho paura di no - abbiamo finito per passare a un formato non XML per lo scambio di dati, rendendo la domanda discutibile. – Aron