XSD 对特定类型的同级元素属性的唯一约束 [英] XSD unique constraint on attribute of sibling elements of a specific type

查看:17
本文介绍了XSD 对特定类型的同级元素属性的唯一约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构为 Q&A 的 XML 文档,它遵循以下格式(为清晰起见进行了编辑):

I have an XML document structured as Q&A which follows the following format (edited for clarity):

<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 如下所示:

My XSD looks like this:

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

当然,它比您在上面看到的更多,但这说明了我的问题.我需要 answer 元素上的 id 属性在兄弟姐妹中是唯一的.上面定义的 XSD 强制 id 属性在兄弟元素之间的唯一性,但它不区分元素类型.我在唯一约束中尝试了各种选择器和字段,但没有找到有效的组合.有什么建议吗?

There is, of course, more to it than what you see above but this illustrates my problem. I need for the id attribute on answer elements to be unique among siblings. The XSD defined above enforces uniqueness of id attributes among sibling elements, but it does not discriminate on element type. I've tried a variety of selectors and fields in the unique constraint, but have not found a combination that works. Any suggestions?

推荐答案

只需将选择器更改为 <xs:selector xpath="answer"/> 就可以了.一般来说,最好避免使用像 .//* 这样的 XPath,如果只是出于性能原因的话.

Just change the selector to <xs:selector xpath="answer"/> and you'll be fine. In general it is good to avoid XPaths like .//*, if only for performance reasons.

这是您提供的 XML 示例的 XML 架构,我认为它正在按照您想要的方式工作:

This is the XML Schema for the XML sample you've provided that I think is working the way you want:

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

Your posted XML validates fine with the above; duplicating any sibling answer's id yields a validation error. For example, the following 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 中的消息类似,因为它基于相同的技术),这些是错误:

When validated (in QTAssistant, should be similar to the message in Visual Studio since it is based on the same technology), these are the errors:

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 验证;虽然这些问题被无意中报告为警告,但它们仍然被报告.

Below is a screenshot from Visual Studio 2010 showing the above XML validation against the XSD I've posted; while the problems are inadvertently reported as warnings, they are, nonetheless, reported.

我随机选择了一个在线验证器(http://xsdvalidation.utilities-online.info/) 并验证了我发布的相同 XML 和 XSD;报错为:

I've randomly picked an online validator (http://xsdvalidation.utilities-online.info/) and validated the same XML and XSD I've posted; the error is reported as:

org.xml.sax.SAXParseException:为元素问题"的身份约束声明的重复唯一值 [1].org.xml.sax.SAXParseException:为元素的身份约束声明的重复唯一值 [1]问题".

您必须注意的一件事是当您有一个 XSD 的目标命名空间时;在这种情况下,需要为所有涉及的命名空间定义一个别名,并在您的选择器中使用它们.

One thing you have to pay attention to is when you have a target namespace for your XSD; in that case, it is needed to define an alias for all of the involved namespaces, and use them in your selectors.

更新:以及带有命名空间的 XSD:

UPDATE: And the XSD with namespaces:

<?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前缀的引入和在选择器中的使用.

Please notice the introduction of the tns prefix and the use of it in the selector.

这篇关于XSD 对特定类型的同级元素属性的唯一约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆