问题
I'm having issues with schema validation, this is my xml
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='favorites.xsd'>
<Favorites>
<Folder>
<Name>Entertainment</Name>
<Bookmarks>
<Bookmark ID="1"/>
<Bookmark ID="200"/> <!-- This should fail validation -->
</Bookmarks>
</Folder>
</Favorites>
<Bookmarks>
<Bookmark>
<ID>1</ID>
<URL>www.website1.com</URL>
</Bookmark>
<Bookmark>
<ID>2</ID>
<URL>www.website2.com</URL>
</Bookmark>
<Bookmark>
<ID>3</ID>
<URL>www.website3.com</URL>
</Bookmark>
</Bookmarks>
</root>
The ID element in Bookmark should be the key, and the Favorites/Folder/Bookmarks/Bookmark ID attribute should always reference a Bookmark ID.
Here is my xsd:
<?xml version="1.0"?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="Favorites" type="Favorites"/>
<xs:element name="Bookmarks" type="Bookmarks"/>
</xs:sequence>
</xs:complexType>
<xs:keyref name="bookmarkIDKeyRef" refer="bookmarkIDKey">
<xs:selector xpath="root/Favorites/Folder/Bookmarks/*"/>
<xs:field xpath="@ID"/>
</xs:keyref>
<xs:key name="bookmarkIDKey">
<xs:selector xpath="root/Bookmarks/Bookmark/ID"/>
<xs:field xpath="ID"/>
</xs:key>
</xs:element>
<xs:complexType name="Favorites">
<xs:sequence maxOccurs="unbounded">
<xs:element name="Folder" type="Folder"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Folder">
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Bookmarks">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="Bookmark">
<xs:complexType>
<xs:attribute name="ID" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Bookmarks">
<xs:sequence maxOccurs ="unbounded">
<xs:element name="Bookmark" type="Bookmark"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Bookmark">
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="URL" type ="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The xml is well formed, but the validation on the ID attribute is not working.
回答1:
The context of your keys is the <root>
element, because in the schema they are children of the <xs:element name="root">
element. Therefore your <xs:selector>
XPaths fail, because they begin with root/...
which is not a child of the <root>
element. Drop it for both key
and keyref
. Also the <xs:field>
of the key fails due to similar issue. You already select the <ID>
element as the context and then try to look for an <ID>
child for this element. Switch the XPath of the <xs:field>
to .
(a dot) or drop the trailing /ID
from the selector.
Here is a working code sample.
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="Favorites" type="Favorites"/>
<xs:element name="Bookmarks" type="Bookmarks"/>
</xs:sequence>
</xs:complexType>
<xs:keyref name="bookmarkIDKeyRef" refer="bookmarkIDKey">
<xs:selector xpath="Favorites/Folder/Bookmarks/*"/>
<xs:field xpath="@ID"/>
</xs:keyref>
<xs:key name="bookmarkIDKey">
<xs:selector xpath="Bookmarks/Bookmark"/>
<xs:field xpath="ID"/>
</xs:key>
</xs:element>
来源:https://stackoverflow.com/questions/8273312/xsd-key-and-keyref-validation