【问题标题】:XML validation using XML Schema使用 XML Schema 进行 XML 验证
【发布时间】:2018-04-10 01:12:11
【问题描述】:

我正在尝试编写一个 XML Schema,它将验证如下所示的 XML 文档。出于验证目的,我使用 xs:unique。我正在尝试将树转换为 XML。所以从根开始会有很多分支。一个路径中从根到叶的实体名称必须是唯一的。示例路径:

name0>scenarioDec>Entities>entityMultiAsp>Entity2>entitySpec>Entity2

在这个路径中Entity2添加了两次。所以它不行。我无法解决这个问题。

另一条路径:

name0>scenarioDec>Events>eventMultiAsp>Aircraft>entitySpec>Entity2

这里 Entity2 没问题。因为在这个路径中之前没有添加Entiy2。

我尝试过使用

<xs:selector xpath=".//entity"/> 

而不是

<xs:selector xpath="*/entity"/>. 

如果我使用 .// 那么它正在检查所有路径。但我只需要一个路径唯一性。

我该如何解决这个问题?

<?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="file:/M:/axm.xsd"
 name="name0">

 <aspect name="scenarioDec">

  <entity name="Environment">
  <!-- for test -->
  </entity>

  <entity name="Entities"> <!-- -->
   <multiAspect name="entityMultiAsp">
    <entity name="Entity2">
     <specialization name="entitySpec">
      <entity name="Aircraft"/>
      <entity name="Entity2"> <!-- it is not ok because in this path already one Entity2 added before.
       name0>scenarioDec>Entities>entityMultiAsp>Entity2>entitySpec>Entity2-->
        <var name="var1"></var>
        <var name="var2"></var>                 
     </entity>
     </specialization>
    </entity>
   </multiAspect>
  </entity>

  <entity name="Events">
   <multiAspect name="eventMultiAsp">
    <entity name="Aircraft"> <!-- it is ok -->
     <specialization name="entitySpec">
      <entity name="Entity2"> <!-- it is ok because in this path no Entity2 is added before 
      name0>scenarioDec>Events>eventMultiAsp>Aircraft>entitySpec>Entity2-->
       <var name="var1"></var>
       <var name="var2"></var>       
      </entity>      
     </specialization>     
    </entity>
   </multiAspect>
  </entity>

 </aspect>

</entity>

上述 XML 的 XML 架构如下所示:

<?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"> <!--  mixed="true" -->
    <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 .//* satisfies empty($x//*[node-name(.) = node-name($x)])"/>

    </xs:complexType>


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


</xs:schema>

在这里我添加了一张图片以使概念清晰。

....... 编辑2: ........

<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="empty(../@name)"/>

        <!--                
            Your suggestion: 
                <xs:assert test="empty(../Entity2)"/>
            but for my case may be it will be  
            <xs:assert test="empty(../@name)"/>

            as entity name is not fixed. I have tried both the way but it is not working. 
        -->

    </xs:complexType>

-----编辑 3--------

我有四种类型的节点:1. Entity,2. MultiAspect,3. Aspect 和 4. Specialization。如果节点是实体,那么它的后继节点是 Aspect、MultiAspect 或 Specialization。如果节点的类型是 Aspect、MultiAspect 或 Specialization,则其子节点的类型是 Entity。根节点始终是实体。

我使用上述规则设计了我的 XML 模式。我使用“assert”来验证 XML 文件。我用过

every $x in .//* satisfies empty($x//*[node-name(.) = node-name($x)])

并且还尝试使用实体而不是 *

every $x in .//entity satisfies empty($x//entity[node-name(.) = node- name($x)])

但它一直显示错误。上面给出了 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="file:/M:/axm.xsd" name="name0">

 <aspect name="scenarioDec">
  <entity name="Environment">
   <multiAspect name="entityMAsp">
    <!-- <entity name="EntityTest"></entity>  --> <!-- if i add "EntityTest" 
as an entity then it shows error but it should be correct -->
   </multiAspect>
  </entity>

 </aspect>


</entity>

当我尝试添加以下行时,在“multiAspect”内部显示错误。

<entity name="EntityTest">

但它应该是正确的。

【问题讨论】:

  • 对不起,我不明白这个问题。我在理解您的路径符号 (a>b>c) 和理解您的英语方面都有问题(例如“因为在此路径中之前没有添加 Entiy2”)。给出有效和无效 XML 的示例会有所帮助。
  • 亲爱的 Michael Kay,对不起我的英语不好。现在我添加了一张图片,以便您理解我的问题。

标签: xml validation xsd schema unique


【解决方案1】:

感谢您的额外解释,我想我现在明白您想要实现的目标了。

我认为这个约束不能在 XSD 1.0 中表达。在 XSD 1.1 中,它可以通过断言来完成:

<xs:element name="Entity2">
 ...
 <xsl:assert test="empty(.//Entity2)"/>
</xs:element>

【讨论】:

  • 亲爱的迈克尔,我尝试使用您的建议,但它不起作用。可能是我没有在应该添加的正确位置添加。 Entity2 不是我的固定名称。它可以是任何名称,但根据该图像,它在从树的根到叶的任何路径中应该是唯一的。抱歉,我可能仍然无法让您了解我实际上要做什么。我真的很抱歉。如果您查看我的编辑 2,那么您可能会明白。谢谢。
  • 好吧,你可以在根元素的声明中声明文档中的任何元素都不能有同名的后代:那就是test="every $x in .//* satisfies empty($x//*[node-name(.) = node-name($x)])"
  • 亲爱的 Michael Kay, 从最近几天开始,我正在尝试使用您的建议。我也在看你的书。但不幸的是,我还不能解决这个问题。我添加了编辑 3 部分。请看那个部分。我真的很努力。我要求你再检查一次。请给我一些建议,以便我完成这项任务。
  • 您似乎有一个文档以“实体”为根,另一个“实体”为后代。你有一个断言说没有元素可能有同名的后代。您的实例文档显然不满足该断言。
  • 当您指的是名为“name”的属性的值时,您谈论元素的名称可能会让我(也可能是您自己)感到困惑。也许在您的断言中,您应该将node-name(.) 替换为@name
猜你喜欢
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 2016-02-03
  • 1970-01-01
  • 2013-03-22
  • 2011-07-24
  • 1970-01-01
  • 2020-12-01
相关资源
最近更新 更多