Xsd 关于在序列中的xsi:type上使用xs:unique
是否可以对元素的类型具有唯一约束 假设我有一艘诺亚方舟,其中动物的/@名称必须是唯一的 下面是一个不根据架构进行验证的XML:Xsd 关于在序列中的xsi:type上使用xs:unique,xsd,unique,Xsd,Unique,是否可以对元素的类型具有唯一约束 假设我有一艘诺亚方舟,其中动物的/@名称必须是唯一的 下面是一个不根据架构进行验证的XML: <ns:NoahsArk xmlns:ns="http://www.xxx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.xxx.com Persons.xsd"> <Animal xs:type="ns:Dog"
<ns:NoahsArk xmlns:ns="http://www.xxx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.xxx.com Persons.xsd">
<Animal xs:type="ns:Dog" ns:name="Gipsy" ns:pedigree="caniche"/>
<Animal xs:type="ns:Spider" ns:name="Gipsy" ns:legNumber="5"/>
</ns:NoahsArk>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://www.xxx.com"
targetNamespace="http://www.xxx.com" elementFormDefault="unqualified" attributeFormDefault="qualified">
<xs:element name="NoahsArk">
<xs:complexType>
<xs:sequence>
<xs:element name="Animal" maxOccurs="unbounded" type="ns:Animal"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="NameUnicity">
<xs:selector xpath="Animal"/>
<xs:field xpath="@ns:name"/>
</xs:unique>
</xs:element>
<xs:complexType name="Animal" abstract="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Dog">
<xs:complexContent>
<xs:extension base="ns:Animal">
<xs:attribute name="pedigree" type="xs:string" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Spider">
<xs:complexContent>
<xs:extension base="ns:Animal">
<xs:attribute name="legNumber" type="xs:integer" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
这很好,但现在让我们假设我想要一艘诺亚方舟,在那里,Animal/@xsi:type是独一无二的
我尝试了这个约束:
<xs:unique name="AnimalUnicity">
<xs:selector xpath="Animal"/>
<xs:field xpath="@xs:type"/>
</xs:unique>
但此XML仍然有效:
<?xml version="1.0" encoding="UTF-8"?>
<ns:NoahsArk xmlns:ns="http://www.xxx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.xxx.com Persons.xsd">
<Animal xs:type="ns:Dog" ns:name="Pierre-Louis" ns:pedigree="doberman"/>
<Animal xs:type="ns:Spider" ns:name="Gipsy" ns:legNumber="5"/>
</ns:NoahsArk>
有什么想法吗
谢谢,
-E我可以在XSD 1.0上测试的所有实现似乎都同意一件事:只有当选择器/字段与可以找到关联的用户定义模式组件的XML节点匹配时,才会测试,虽然它是一个与模式相关的标记,但由于其意图不同,这里不考虑它。在学术上,检查Schematron断言是否有助于 更新:我也包括了Schematron版本;自从我在.NET上以来,我一直在运行ISO版本XSLT1和Microsoft扩展
<?xml version="1.0"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:ms="urn:schemas-microsoft-com:xslt">
<sch:ns uri="http://www.w3.org/2001/XMLSchema-instance" prefix="xsi"/>
<sch:ns uri="urn:schemas-microsoft-com:xslt" prefix="ms"/>
<sch:pattern id="about-using-xsunique-on-xsitype-in-a-sequence">
<sch:rule context="//Animal/@xsi:type">
<sch:let name="targetNodeSet" value="//Animal/@xsi:type"/>
<sch:assert test="count($targetNodeSet[concat('{', ms:namespace-uri(.), '}', ms:local-name(.)) = concat('{', ms:namespace-uri(current()), '}', ms:local-name(current()))]) = 1">
Only one-of-a-kind animal is allowed.</sch:assert>
<sch:assert test="count($targetNodeSet[. = current()]) = 1">
Only one-of-a-kind animal is allowed (naive).</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
我定义了两个断言,一个简单的断言通过文本比较xsi:type属性的值;和正确的一个比较它们作为QName s
对于此XML:
<ns:NoahsArk xmlns:ns1="http://www.xxx.com" xmlns:ns="http://www.xxx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.xxx.com Persons.xsd">
<Animal xs:type="ns:Dog" ns:name="A" ns:pedigree="caniche"/>
<Animal xs:type="ns1:Dog" ns:name="B" ns:pedigree="caniche"/>
<Animal xs:type="ns1:Dog" ns:name="C" ns:pedigree="caniche"/>
</ns:NoahsArk>
结果是:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<svrl:schematron-output title="" schemaVersion="" xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:schold="http://www.ascc.net/xml/schematron" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns:iso="http://purl.oclc.org/dsdl/schematron" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ms="urn:schemas-microsoft-com:xslt">
<svrl:ns-prefix-in-attribute-values uri="http://www.w3.org/2001/XMLSchema-instance" prefix="xsi"/>
<svrl:ns-prefix-in-attribute-values uri="urn:schemas-microsoft-com:xslt" prefix="ms"/>
<svrl:active-pattern id="about-using-xsunique-on-xsitype-in-a-sequence" name="about-using-xsunique-on-xsitype-in-a-sequence"/>
<svrl:fired-rule context="//Animal/@xsi:type"/>
<svrl:failed-assert test="count($targetNodeSet[concat(', ms:namespace-uri(.), ', ms:local-name(.)) = concat(', ms:namespace-uri(current()), ', ms:local-name(current()))]) = 1" location="/@*[local-name()='type' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']">
<svrl:text>
Only one-of-a-kind animal is allowed.</svrl:text>
</svrl:failed-assert>
<svrl:fired-rule context="//Animal/@xsi:type"/>
<svrl:failed-assert test="count($targetNodeSet[concat(', ms:namespace-uri(.), ', ms:local-name(.)) = concat(', ms:namespace-uri(current()), ', ms:local-name(current()))]) = 1" location="/@*[local-name()='type' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']">
<svrl:text>
Only one-of-a-kind animal is allowed.</svrl:text>
</svrl:failed-assert>
<svrl:failed-assert test="count($targetNodeSet[. = current()]) = 1" location="/@*[local-name()='type' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']">
<svrl:text>
Only one-of-a-kind animal is allowed (naive).</svrl:text>
</svrl:failed-assert>
<svrl:fired-rule context="//Animal/@xsi:type"/>
<svrl:failed-assert test="count($targetNodeSet[concat(', ms:namespace-uri(.), ', ms:local-name(.)) = concat(', ms:namespace-uri(current()), ', ms:local-name(current()))]) = 1" location="/@*[local-name()='type' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']">
<svrl:text>
Only one-of-a-kind animal is allowed.</svrl:text>
</svrl:failed-assert>
<svrl:failed-assert test="count($targetNodeSet[. = current()]) = 1" location="/@*[local-name()='type' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']">
<svrl:text>
Only one-of-a-kind animal is allowed (naive).</svrl:text>
</svrl:failed-assert>
</svrl:schematron-output>
从失败的断言中可以看出,朴素的方法只标记了3个实例中的2个;同样,将xsi:type属性的值作为文本进行比较与比较QName s不同,QName s就是@xsi:types。感谢您的回答 只是为了好玩,我尝试使用Schematron;但是,我无法使其工作,因为我发现的XPath表达式使用的是当前表达式,而这在oxygen或XMLSpy中不可用,因此我无法测试它:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.ascc.net/xml/schematron" xmlns:ns="http://www.xxx.com" >
<ns prefix="ns" uri="http://www.xxx.com"/>
<ns prefix="xs" uri="http://www.w3.org/2001/XMLSchema-instance"/>
<pattern name="AnimalNameUnicity">
<rule context="Animals/Animal">
<assert test="count(//@ns:name[ . = current()]) > 1">name not unique !</assert>
</rule>
</pattern>
</schema>
嗯,还有很多。。。例如,如果ns1和ns别名映射到同一命名空间,则ns1:Dog和ns:Dog可能相同,如果不是,则不同。我的方法会有所不同,因为我不会在这里使用schematron的旧版本1.5;我将使用ISO one,更具体地说,首先为@xsi:type编写XSD约束,但是使用从XSD到Schematron的转换来启动模式-请参阅本文以了解更多信息。谢谢Petru。这将符合我的需要,但我不确定Schematron验证有多困难。使用XMLSpy,似乎需要一个插件-。使用氧气时,我无法使其工作。请参阅下面的错误消息。引擎名称:ISO Schematron严重性:错误描述:URI urn:schemas microsoft com:xslt未识别外部Java类。我还惊讶于.NET framework似乎没有自己的Schematron验证实现[也许我错了?]。我担心GSoap也不支持它,使用soapUI进行调试/测试,我希望它能够对输入/输出消息执行验证,但它只能针对XSD进行验证。@Eniac,正如我所提到的,我在.NET上,它仅限于XSLT1.0开箱即用。是的,.NET没有内置Schematron;但是,我已经在.NET上使用www.schematron.com上的XSLT1.0构建了自己的XSLT1.0。