不确定这是否可行,但我想用xsd(版本1.1)验证xml文档中使用的变量是在同一文档的不同部分中指定的。
我的文档的一部分如下所示:
<bf:Variables>
<bf:Variable name="myVariable">
...
</bf:Variable>
<bf:Variable name="AnotherOne">
...
</bf:Variable>
<bf:Variable name="evenMore">
...
</bf:Variable>
...
</bf:Variables>
然后在同一个文档中,我有另一个看起来像这样的部分:
<bf:Restrictions>
<bf:Restriction variable="myVariable" operator="=">
<bf:Value>True</bf:Value>
</bf:Restriction>
<bf:Restriction variable="AnotherOne" operator="=">
<bf:Value>False</bf:Value>
</bf:Restriction>
<bf:Restriction variable="ThirdVariable" operator="=">
<bf:Value>False</bf:Value>
</bf:Restriction>
</bf:Restrictions>
我的目标是检查限制部分中使用的变量是否在变量部分中指定。 在上面的示例中,“ThirdVariable”应该无法通过xsd检查,因为它在“变量”部分中不存在。
答案 0 :(得分:0)
这可以通过几种方式解决,有些方面比其他方式更好
使用断言的解决方案 - 但不是很好......
在XSD 1.1中,您可以使用<xs:assert>
执行此操作。理想情况下,断言将放在引用元素<Restriction>
上,这样就可以明确<Restriction>
无效。
但是,由于<xs:assert>
无法访问树中较高的值,因此<xs:assert>
必须足够高才能使<Restriction>
和<Variable>
位于其中范围(儿童)。这样就可以了,但是现在你必须写一个通用规则,如果它失败将无法提供太多反馈 - 它只会告诉你一个或多个<Restriction>
无效。
下面是一个非常快速的样本来展示。
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="base">
<xs:complexType>
<xs:sequence>
<xs:element name="var" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="Usage" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:assert test="count(Usage[not(./text() = ../var/text())]) = 0" />
</xs:complexType>
</xs:element>
</xs:schema>
示例XML
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2016 Developer Bundle Edition 14.1.4.6649 (https://www.liquid-technologies.com) -->
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Schema.xsd">
<var>var1</var>
<var>var2</var>
<var>var4</var>
<Usage>var1</Usage>
<Usage>var2</Usage>
<Usage>var3</Usage><!-- INVALID -->
</base>
错误消息(通过Saxon)
(10:7)关键cvc-assertion:断言评估('count(用法[not(./ text()= ../ var / text())])= 0')元素'base'on模式类型'#AnonType_base'未成功。
使用Key / KeyRef的更好解决方案
这是XSD 1.0友好的,效果很好。它告诉您是否有重复的可变名称,以及变量名称引用是否无效,指出实际问题。
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="base">
<xs:complexType>
<xs:sequence>
<xs:element name="Variables">
<xs:complexType>
<xs:sequence>
<xs:element name="Variable" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Restrictions">
<xs:complexType>
<xs:sequence>
<xs:element name="Restriction" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="variable" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="VarDef">
<xs:selector xpath="./Variables/Variable" />
<xs:field xpath="@name" />
</xs:key>
<xs:keyref name="VarRef" refer="VarDef">
<xs:selector xpath="./Restrictions/Restriction" />
<xs:field xpath="@variable" />
</xs:keyref>
</xs:element>
</xs:schema>
示例XML
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com) -->
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SchemaKeyRef.xsd">
<Variables>
<Variable name="var1"></Variable>
<Variable name="var2"></Variable>
<Variable name="var3"></Variable>
</Variables>
<Restrictions>
<Restriction variable="var1">string</Restriction>
<Restriction variable="var2">string</Restriction>
<Restriction variable="UNKNOWN">string</Restriction>
</Restrictions>
</base>
现在生成的错误更加具体,使得调试问题变得更加容易。
来自.Net的错误(行号是错误的限制)
(12:10)错误'VarDef'Keyref中的键序列'UNKNOWN'无法引用某个键。
Saxon的错误(行号是包含元素库)
(14:7)严重的cvc-identity-constraint.4.3:找不到元素'base'的标识约束的值为'UNKNOWN'的键'VarRef'。