我有一个结构化为Q& A的
XML文档,遵循以下格式(为了清楚起见,进行了编辑):
<question> <answer id="1"> <question> <answer id="1"/> <answer id="2"/> <answer id="3"/> </question> </answer> <answer id="2"> <question> <answer id="1"/> <answer id="2"/> </question> </answer> </question>
我的XSD看起来像这样:
<xs:element name="question"> <xs:complexType> <xs:sequence> <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"> </xs:element> </xs:sequence> </xs:complexType> <xs:unique name="AnswerIdUnique"> <xs:selector xpath="./*" /> <xs:field xpath="@id" /> </xs:unique> </xs:element> <xs:complexType name="answerType"> <xs:sequence> <xs:element ref="question" minOccurs="0" maxOccurs="1" /> </xs:sequence> <xs:attribute name="id" type="xs:token" use="required" /> </xs:complexType>
当然,比上面看到的更多,但这说明了我的问题.
我需要对答案元素的id属性在兄弟姐妹中是独一无二的.上面定义的XSD可以实现兄弟元素之间的id属性的唯一性,但它不区分元素类型.我已经尝试了各种选择器和字段的唯一约束,但没有找到有效的组合.
有什么建议么?
只需将选择器更改为< xs:selector xpath =“answer”/>你会没事的.一般来说,避免XPath像////,如果只是出于性能原因是好的.
这是您提供的XML示例的XML模式,我认为这是您想要的方式:
<?xml version="1.0" encoding="utf-8" ?> <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="question" type="questionType"> <xs:unique name="AnswerIdUnique"> <xs:selector xpath="answer"/> <xs:field xpath="@id"/> </xs:unique> </xs:element> <xs:complexType name="questionType"> <xs:sequence> <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="answerType"> <xs:sequence> <xs:element ref="question" minOccurs="0" maxOccurs="1"/> </xs:sequence> <xs:attribute name="id" type="xs:token" use="required"/> </xs:complexType> </xs:schema>
您发布的XML可以使用上述内容进行验证;复制任何兄弟的答案的ID会产生验证错误.例如,以下XML:
<question> <answer id="1"> <question> <answer id="1"/> <answer id="2"/> <answer id="1"/> </question> </answer> <answer id="1"> <question> <answer id="1"/> <answer id="2"/> </question> </answer> </question>
验证(在QTAssistant中,应该类似于Visual Studio中的消息,因为它基于相同的技术),这些是错误:
Error occurred while loading [],line 6 position 5 There is a duplicate key sequence '1' for the 'AnswerIdUnique' key or unique identity constraint. Error occurred while loading [],line 9 position 3 There is a duplicate key sequence '1' for the 'AnswerIdUnique' key or unique identity constraint. Document1.xml is invalid.
以下是Visual Studio 2010的屏幕截图,显示了我发布的XSD的上述XML验证;虽然这些问题被无意地报告为警告,但仍然有报道.
我随机选了一个在线验证器(http://xsdvalidation.utilities-online.info/),验证了我发布的相同的XML和XSD;错误报告为:
org.xml.sax.SAXParseException:为元素“question”的identity约束声明的唯一重复值[1] .org.xml.sax.SAXParseException:为元素“question”的身份约束声明的唯一值[1].
有一件事你要注意的是当你有一个XSD的目标命名空间;在这种情况下,需要为所有涉及的命名空间定义别名,并在选择器中使用别名.
更新:XSD与命名空间:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://localhost" xmlns="http://localhost" targetNamespace="http://localhost" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="question" type="questionType"> <xs:unique name="AnswerIdUnique"> <xs:selector xpath="tns:answer"/> <xs:field xpath="@id"/> </xs:unique> </xs:element> <xs:complexType name="questionType"> <xs:sequence> <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="answerType"> <xs:sequence> <xs:element ref="question" minOccurs="0" maxOccurs="1"/> </xs:sequence> <xs:attribute name="id" type="xs:token" use="required"/> </xs:complexType> </xs:schema>
请注意tns前缀的介绍和它在选择器中的使用.