Reputation: 2644
I have an xml describing vertices on a directed graph:
<graph>
<vertex id="a">
<edge target="b"/>
</vertex>
<vertex id="b"/>
</graph>
Given the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="vertex">
<xs:sequence>
<xs:element type="edge" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" use="required" type="xs:string"/>
</xs:complexType>
<xs:complexType name="edge">
<xs:attribute name="target" use="required"/>
</xs:complexType>
<xs:complexType name="graph">
<xs:sequence>
<xs:element name="vertex" type="vertex" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="graph" type="graph"/>
</xs:schema>
How can I modify the target
attribute so it's value can only be valid vertex id's?
so my initial example is a valid xml but:
<graph>
<vertex id="a">
<edge target="c"/>
</vertex>
<vertex id="b"/>
</graph>
is not.
Upvotes: 1
Views: 151
Reputation: 122414
You can do this with a key/keyref pair. Define them at the graph
level, to enforce that the vertex
IDs are unique:
<xs:element name="graph" type="graph">
<xs:key name="vertexKey">
<xs:selector xpath="vertex" />
<xs:field xpath="@id" />
</xs:key>
<xs:keyref name="edgeRef" refer="vertexKey">
<xs:selector xpath="vertex/edge" />
<xs:field xpath="@target" />
</xs:keyref>
</xs:element>
Importantly, you also need to add a type
to the target
attribute of edge
, as the types of the key and the reference must be compatible:
<xs:complexType name="edge">
<xs:attribute name="target" type="xs:string" use="required"/>
</xs:complexType>
(additionally the edge
element under the vertex
type is missing a name
, but I presume this is a copy/paste mistake as the validator would have complained more loudly if your real schema were like that)
Upvotes: 3