在XML模式中使用assert,以便在特定条件满足时不允许节点出现

时间:2014-09-24 12:39:05

标签: xml xpath xsd

如果我想表达以下内容,我应该在assert语句中写一下:在XML文件中,每当A节点出现时,B节点或C节点或两者都应该出现,使得A \ @OID eq B \ @OID和A \ @OID eq C \ @OID。基本上,关于提供的XML,不应出现具有OID = HHH的最后一个A节点。

以下是XML Schema文档:

<?xml version="1.0" encoding="UTF-8"?>
<!--<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1">
	<xs:element name="Document">
		<xs:complexType>
			<xs:sequence maxOccurs="unbounded">
				<xs:element ref="A" minOccurs="0" maxOccurs="unbounded"/>
				<xs:element ref="B" minOccurs="0" maxOccurs="unbounded"/>
				<xs:element ref="C" minOccurs="0" maxOccurs="unbounded"/>
			</xs:sequence>
			<xs:assert test="every $a in A, $b in B[@OID eq $a/@OID] satisfies $a/@A_Membership_Degree ge $b/@B_Membership_Degree"/>
			<xs:assert test="every $a in A, $c in C[@OID eq $a/@OID] satisfies $a/@A_Membership_Degree ge $c/@C_Membership_Degree"/>
		</xs:complexType>
		<xs:key name="aKey">
			<xs:selector xpath="A"/>
			<xs:field xpath="@OID"/>
		</xs:key>
		<xs:key name="bKey">
			<xs:selector xpath="B"/>
			<xs:field xpath="@OID"/>
		</xs:key>
		<xs:key name="cKey">
			<xs:selector xpath="C"/>
			<xs:field xpath="@OID"/>
		</xs:key>
		<xs:keyref name="aKeyRef" refer="aKey">
			<xs:selector xpath="./B"/>
			<xs:field xpath="@OID"/>
		</xs:keyref>
		<xs:keyref name="aKeyRef1" refer="aKey">
			<xs:selector xpath="./C"/>
			<xs:field xpath="@OID"/>
		</xs:keyref>
	</xs:element>
	<xs:element name="A" type="Atype"/>
	<xs:complexType name="Atype">
		<xs:sequence minOccurs="0" maxOccurs="unbounded">
			<xs:element name="A1" type="xs:string" minOccurs="1" maxOccurs="1"/>
			<xs:element name="A2" type="xs:string" minOccurs="1" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="OID" type="xs:string" use="required"/>
		<xs:attribute name="A_Membership_Degree" type="FuzzyValue" use="optional"/>
	</xs:complexType>
	<xs:element name="B" type="Btype"/>
	<xs:complexType name="Btype">
		<xs:sequence>
			<xs:element name="B1" type="xs:string" minOccurs="1" maxOccurs="1"/>
			<xs:element name="B2" type="xs:string" minOccurs="1" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="OID" type="xs:string" use="required"/>
		<xs:attribute name="B_Membership_Degree" type="FuzzyValue" use="optional"/>
	</xs:complexType>
	<xs:element name="C" type="Ctype"/>
	<xs:complexType name="Ctype">
		<xs:sequence>
			<xs:element name="C1" type="xs:string" minOccurs="1" maxOccurs="1"/>
			<xs:element name="C2" type="xs:string" minOccurs="1" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="OID" type="xs:string" use="required"/>
		<xs:attribute name="C_Membership_Degree" type="FuzzyValue" use="required"/>
	</xs:complexType>
	<xs:simpleType name="FuzzyValue">
		<xs:restriction base="xs:decimal">
			<xs:minInclusive value="0"/>
			<xs:maxInclusive value="1"/>
		</xs:restriction>
	</xs:simpleType>
</xs:schema>
 

以下XML文档不应该有效,因为不应出现具有OID = HHH的最后一个A节点。

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="gen.xsd">
<A OID="AA" A_Membership_Degree="0.7" >
  <A1>X1</A1>
  <A2>D1</A2>
 </A>
 <B OID="AA" B_Membership_Degree="0.6" >
  <B1>G1</B1>
  <B2>F1</B2>
 </B>
  <C  OID="AA" C_Membership_Degree="0.3" >
  <C1>G2</C1>
  <C2>F2</C2>
 </C>
 
<A OID="AAA" A_Membership_Degree="0.8"  >
  <A1>X2</A1>
  <A2>D2</A2>
 </A>
  <B OID="AAA" B_Membership_Degree="0.2"  >
  <B1>G3</B1>
  <B2>F3</B2>
 </B>   
 <A OID="HHH" A_Membership_Degree="0.8" >
  <A1>X11</A1>
  <A2>D11</A2>
 </A>

</Document>

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

  

在XML文件中,每当出现A节点时,B节点或C节点或两者都应该出现,使得A \ @OID eq B \ @OID和A \ @OID eq C \ @OID。

听起来像是

<xs:assert test="every $a in A satisfies 
  (exists(B[@OID eq $a/@OID]) or exists(C[@OID eq $a/@OID]))"/>

可以缩短为

<xs:assert test="every $a in A satisfies (B|C)[@OID eq $a/@OID]"/>