Validation 如何验证一个XSD模式是另一个XSD模式的子集?

Validation 如何验证一个XSD模式是另一个XSD模式的子集?,validation,xsd,schema,subset,Validation,Xsd,Schema,Subset,如何验证一个XSD模式是另一个XSD模式的子集 我们正在使用一组“blueprint”XSD模式(定义子组件可用的所有可能输入或输出)创建一个system of systems应用程序。正在实现许多子组件,这些子组件使用XML文件在它们之间传递数据。每个子组件创建相关blueprint XSD模式的一个子集(以指示它选择实现哪些可能的输入或输出)。任何针对子集XSD模式进行验证的XML数据文件也必须针对blueprint XSD模式进行验证,但情况并非如此(因为子集XSD模式可能不包含bluep

如何验证一个XSD模式是另一个XSD模式的子集

我们正在使用一组“blueprint”XSD模式(定义子组件可用的所有可能输入或输出)创建一个system of systems应用程序。正在实现许多子组件,这些子组件使用XML文件在它们之间传递数据。每个子组件创建相关blueprint XSD模式的一个子集(以指示它选择实现哪些可能的输入或输出)。任何针对子集XSD模式进行验证的XML数据文件也必须针对blueprint XSD模式进行验证,但情况并非如此(因为子集XSD模式可能不包含blueprint XSD模式中的所有“可选”或“选择”XML元素,并且它可能会选择进一步限制现有XML标记上允许的数据值)。系统将根据子组件的子集XSD模式验证子组件的所有XML输入(以标记任何错误输入并隔离数据相关问题的来源)

在测试期间,我们打算验证每个子组件的子集XSD模式是否确实是关联blueprint XSD模式的子集,但我们没有自动执行此验证的方法。这些XSD模式非常大,而且非常难看,需要手工进行测试。最好有一种“validate XSD file 1against XSD file 2”命令,类似于Java如何根据XSD模式执行XML文件的验证。我们希望确认每个子组件的子集XSD模式将不允许任何违反blueprint XSD模式的XML输入/输出组合。使用这种模式到模式的功能,验证子组件A的输出XML是否适合用作子组件B的输入也将非常有用(我们可以轻松地根据XSD模式验证单个输出XML,但我们希望确认子组件a的所有可能XML输出都将根据子组件B的XSD模式进行验证)


有用信息:此应用程序是作为OSGi捆绑包实现的Java 6应用程序的集合,并使用Maven 2.2.1编译/执行。不要求使用任何特定的开发IDE。该系统正在Microsoft Windows XP环境中测试,但计划在其他环境中执行此系统同样(因此,最好是跨平台解决方案)。

确保所需关系的最简单方法是通过限制blueprint模式的类型来派生子集模式的类型。不过,听起来好像这艘船已经航行过了

和这里的其他人一样,我不知道有任何工具可以做到这一点(尽管如果Petru Gardea说QT Assistant可以做到,那么值得跟进)

一个复杂的问题是,有两种不同的方式来查看要验证的子集/超集关系:(1)模式1接受为有效的每个文档(或元素)也被模式2接受为有效(不参考所做的类型分配),或者(2)通过验证生成的类型化文档(规范称之为模式后验证信息集)与模式1和模式2相反,模式1和模式2彼此之间存在着适当的关系:如果一个元素或属性在树1中有效,那么它在树2中有效;在树1中分配给它的类型是在树2中分配给它的类型的限制;等等。如果模式1和模式2是独立开发的,那么它们的类型通过派生关系相关的可能性很小r、 所以我想你已经想到了解决这个问题的第一种方法

然而,无论是哪种形式,这个问题都是可以确定的。对于任何模式(我正在仔细使用这个术语),根据定义,声明的类型和元素名称的数量都是有限的;因此,元素名称/类型对的数量是有限的(可能很大)

算法可以是这样的

  • 从预期的根元素开始。(如果有多个可能的根元素,那么在一般情况下,您需要对每个根元素都运行此检查。)如果预期的根元素为E,模式1中的类型为T1,模式2中的类型为T2,则将任务“比较类型T1和T2”在打开的任务队列中。已完成的任务列表将为空

  • 要比较两种复杂类型T1和T2:

    • 检查为T1和T2声明的属性集的名称之间的子集/超集关系。确保目标超集中不存在所需的属性,或目标子集中不存在可选属性

    • 为T1和T2声明的每个属性A都将被分配一个类型(称为ST1和ST2)。如果ST1=ST2,则不执行任何操作;否则,将任务“比较简单类型ST1和ST2”添加到打开的任务队列中,除非它在已完成的比较列表中

    • 现在检查T1和T2中可能出现的子级序列——正如13ren在一篇评论中所建议的,这是可以处理的,因为内容模型本质上是正则表达式,使用元素名称集作为其字母表;因此,它们定义的语言是正则的,并且子集/超集关系对于正则语言是可判定的uages

    • 每个可能的子元素C都由父类型T1和T2分配一个元素声明和一个类型定义。让我们称它们为ED1、ED2、CT1和CT2。每个同名的子元素都有相同的类型,但不同的子元素可能匹配不同的元素声明。因此,对于任何可能的名称,只有一对of类型为CT1和CT2,但可能有多对ED1和ED2(分析需要小心,以确保它们正确匹配;这可能很难自动化)

    • 如果CT1=CT2,则不执行任何操作,否则将“比较类型CT1和CT2”放入打开的任务队列中,除非比较
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="root" type="rootType"/>
        <xs:complexType name="rootType">
          <xs:sequence>
            <xs:element name="child1" minOccurs="0"/>
            <xs:element name="child2" minOccurs="0"/>
            <xs:element name="child3" minOccurs="0"/>
          </xs:sequence>
        </xs:complexType>
      </xs:schema>
      
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="root" type="rootType"/>
        <xs:complexType name="rootType">
          <xs:sequence>
            <xs:element name="child2"/>
          </xs:sequence>
        </xs:complexType>
      </xs:schema>
      
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:redefine schemaLocation="blueprintschema.xsd">
          <xs:complexType name="rootType">
            <xs:complexContent>
              <xs:restriction base="rootType">
                <xs:sequence>
                  <xs:element name="child2"/>
                </xs:sequence>
              </xs:restriction>
            </xs:complexContent>
          </xs:complexType>
        </xs:redefine>
        <xs:element name="root" type="rootType"/>
      </xs:schema>