XML XSD1.1 断言中使用 XPath 查询的元素限制
XML element restriction using XPath query in XSD1.1 assert
我写了 "music.xsd" 来验证下面的 "music.xml" 文件。在音乐文件中有两个专业化 styleSpec 和 ensembleSpec。
<specialization name="styleSpec">
<entity name="Symphonic">
</entity>
</specialization>
和
<specialization name="ensembleSpec">
<entity name="Orchestra">
</entity>
</specialization>
"styleSpec" 允许的实体是 Symphonic、Folk 和 Jazz。
"ensembleSpec" 允许的实体是 Orchestra、SmallGroup 和 Soloist。
我想添加以下限制:
如果 styleSpec 中的实体是 Symphonic,那么 ensembleSpec 中的实体必须是 Orchestra。
如果 styleSpec 中的实体是 Folk,则 ensembleSpec 中的实体必须是 SmallGroup 或 Soloist。
如果 styleSpec 中的实体是 Jazz,那么 ensembleSpec 中的实体必须是 Orchestra 或 SmallGroup。
我可以在另一个 XSD 文件中执行此操作(another.xsd,如下所示)但是当我在 music.xsd 中添加该断言语句时它不起作用。
我该如何解决这个问题?
music.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="music.xsd"
name="MusicPerformances">
<multiAspect name="musicPerformancesMAsp">
<entity name="MusicPerformance">
<specialization name="styleSpec">
<entity name="Symphonic">
</entity>
</specialization>
<specialization name="ensembleSpec">
<entity name="Orchestra">
</entity>
</specialization>
</entity>
</multiAspect>
</entity>
music.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:complexType name="aspectType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="multiAspectType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="specializationType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="varType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:element name="entity">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="aspect"/>
<xs:element ref="specialization"/>
<xs:element ref="multiAspect"/>
<xs:element ref="var"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="name" use="required"/>
<xs:assert test="every $x in .//entity satisfies empty($x//*[@name = $x/@name])"/>
<!--
<xs:assert test=
**// Maybe have to add XPath query here. But I am not sure where
i will add.**
/>
-->
</xs:complexType>
<xs:unique name="entityunqall">
<xs:selector xpath="*/entity"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:element name="aspect" type="aspectType"/>
<xs:element name="multiAspect" type="multiAspectType"/>
<xs:element name="specialization" type="specializationType"/>
<xs:element name="var" type="varType"/>
another.xml 文件与 another.xsd 一起正常工作。
another.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:element name="styleSpec">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Symphonic" />
<xs:enumeration value="Folk" />
<xs:enumeration value="Jazz" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ensembleSpec">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Orchestra" />
<xs:enumeration value="SmallGroup" />
<xs:enumeration value="Soloist" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="MusicalPerformance">
<xs:complexType>
<xs:sequence>
<xs:element ref="styleSpec"/>
<xs:element ref="ensembleSpec"/>
</xs:sequence>
<xs:assert test="(styleSpec = 'Symphonic' and ensembleSpec=('Orchestra'))
or
(styleSpec = 'Folk' and ensembleSpec=('SmallGroup','Soloist'))
or
(styleSpec = 'Jazz' and ensembleSpec=('Orchestra','SmallGroup'))
"/>
</xs:complexType>
</xs:element>
</xs:schema>
another.xml
<?xml version="1.0" encoding="UTF-8"?>
<MusicalPerformance xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="another.xsd">
<styleSpec>Folk</styleSpec>
<ensembleSpec>Soloist</ensembleSpec>
</MusicalPerformance>
编辑
我已经更改了音乐文件,新文件如下:
music.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="musicalperformances.xsd"
name="MusicPerformances">
<multiAspect name="MusicPerformancesMAsp">
<entity name="MusicPerformance">
<aspect name="MusicPerformanceDec">
<entity name="Music">
<specialization name="styleSpec">
<entity name="Jazz">
</entity>
</specialization>
</entity>
<entity name="Performer">
<specialization name="ensembleSpec">
<entity name="SmallGroup">
</entity>
</specialization>
</entity>
</aspect>
</entity>
</multiAspect>
</entity>
首先,断言需要在两个特化元素的父元素上进行(即在 multiAspect
元素的级别)。您没有在您的问题或评论中明确说明您提出断言的位置,这可能表明您没有意识到正确执行此操作的重要性。
那么规则就很简单了,例如:
if the entity inside styleSpec is Symphonic then the entity inside
ensembleSpec must be Orchestra.
test="if (specialization[@name='styleSpec']/entity/@name='Symphonic')
then specialization(@name='ensembleSpec']/entity/@name='Orchestra'
else true()"
我写了 "music.xsd" 来验证下面的 "music.xml" 文件。在音乐文件中有两个专业化 styleSpec 和 ensembleSpec。
<specialization name="styleSpec">
<entity name="Symphonic">
</entity>
</specialization>
和
<specialization name="ensembleSpec">
<entity name="Orchestra">
</entity>
</specialization>
"styleSpec" 允许的实体是 Symphonic、Folk 和 Jazz。
"ensembleSpec" 允许的实体是 Orchestra、SmallGroup 和 Soloist。
我想添加以下限制:
如果 styleSpec 中的实体是 Symphonic,那么 ensembleSpec 中的实体必须是 Orchestra。
如果 styleSpec 中的实体是 Folk,则 ensembleSpec 中的实体必须是 SmallGroup 或 Soloist。
如果 styleSpec 中的实体是 Jazz,那么 ensembleSpec 中的实体必须是 Orchestra 或 SmallGroup。
我可以在另一个 XSD 文件中执行此操作(another.xsd,如下所示)但是当我在 music.xsd 中添加该断言语句时它不起作用。
我该如何解决这个问题?
music.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="music.xsd"
name="MusicPerformances">
<multiAspect name="musicPerformancesMAsp">
<entity name="MusicPerformance">
<specialization name="styleSpec">
<entity name="Symphonic">
</entity>
</specialization>
<specialization name="ensembleSpec">
<entity name="Orchestra">
</entity>
</specialization>
</entity>
</multiAspect>
</entity>
music.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:complexType name="aspectType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="multiAspectType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="specializationType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="varType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:element name="entity">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="aspect"/>
<xs:element ref="specialization"/>
<xs:element ref="multiAspect"/>
<xs:element ref="var"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="name" use="required"/>
<xs:assert test="every $x in .//entity satisfies empty($x//*[@name = $x/@name])"/>
<!--
<xs:assert test=
**// Maybe have to add XPath query here. But I am not sure where
i will add.**
/>
-->
</xs:complexType>
<xs:unique name="entityunqall">
<xs:selector xpath="*/entity"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:element name="aspect" type="aspectType"/>
<xs:element name="multiAspect" type="multiAspectType"/>
<xs:element name="specialization" type="specializationType"/>
<xs:element name="var" type="varType"/>
another.xml 文件与 another.xsd 一起正常工作。
another.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:element name="styleSpec">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Symphonic" />
<xs:enumeration value="Folk" />
<xs:enumeration value="Jazz" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ensembleSpec">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Orchestra" />
<xs:enumeration value="SmallGroup" />
<xs:enumeration value="Soloist" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="MusicalPerformance">
<xs:complexType>
<xs:sequence>
<xs:element ref="styleSpec"/>
<xs:element ref="ensembleSpec"/>
</xs:sequence>
<xs:assert test="(styleSpec = 'Symphonic' and ensembleSpec=('Orchestra'))
or
(styleSpec = 'Folk' and ensembleSpec=('SmallGroup','Soloist'))
or
(styleSpec = 'Jazz' and ensembleSpec=('Orchestra','SmallGroup'))
"/>
</xs:complexType>
</xs:element>
</xs:schema>
another.xml
<?xml version="1.0" encoding="UTF-8"?>
<MusicalPerformance xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="another.xsd">
<styleSpec>Folk</styleSpec>
<ensembleSpec>Soloist</ensembleSpec>
</MusicalPerformance>
编辑
我已经更改了音乐文件,新文件如下:
music.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="musicalperformances.xsd"
name="MusicPerformances">
<multiAspect name="MusicPerformancesMAsp">
<entity name="MusicPerformance">
<aspect name="MusicPerformanceDec">
<entity name="Music">
<specialization name="styleSpec">
<entity name="Jazz">
</entity>
</specialization>
</entity>
<entity name="Performer">
<specialization name="ensembleSpec">
<entity name="SmallGroup">
</entity>
</specialization>
</entity>
</aspect>
</entity>
</multiAspect>
</entity>
首先,断言需要在两个特化元素的父元素上进行(即在 multiAspect
元素的级别)。您没有在您的问题或评论中明确说明您提出断言的位置,这可能表明您没有意识到正确执行此操作的重要性。
那么规则就很简单了,例如:
if the entity inside styleSpec is Symphonic then the entity inside ensembleSpec must be Orchestra.
test="if (specialization[@name='styleSpec']/entity/@name='Symphonic')
then specialization(@name='ensembleSpec']/entity/@name='Orchestra'
else true()"