nav*_*ySV 8 validation schema xsd subset
如何验证一个XSD架构是否是另一个XSD架构的子集?
我们正在使用一系列"蓝图"XSD架构(定义子组件可用的所有可能输入或输出)创建系统系统应用程序.正在实现许多子组件,这些子组件使用XML文件在它们之间传递数据.每个子组件创建相关蓝图XSD架构的子集(以指示它选择实现哪些可能的输入或输出).任何针对子集XSD架构验证的XML数据文件也必须针对蓝图XSD架构进行验证,但反之则不然(因为子集XSD架构可能不包含蓝图XSD架构中的所有"可选"或"选择"XML元素,并且它可以选择进一步限制现有XML标记上的允许数据值).系统将针对该子组件的子集XSD架构验证子组件的所有XML输入(标记任何错误输入并隔离数据相关问题的来源).
在测试期间,我们打算验证每个子组件的子集XSD架构是否真的是关联蓝图XSD架构的子集,但我们没有自动执行此验证的方法.这些XSD架构相当庞大且难以手动进行此类测试.有一种"验证XSD文件1对XSD文件2"命令会很好,类似于Java如何根据XSD架构执行XML文件验证.我们要确认每个子组件的子集XSD架构都不允许任何违反蓝图XSD架构的XML输入/输出组合.使用这种模式到模式功能,验证子组件A的输出XML是否适合用作子组件B的输入也是非常有用的(我们可以轻松地针对XSD模式验证单个输出XML,但是我们想确认子组件A的所有可能的XML输出都将针对子组件B的XSD架构进行验证.
有用的信息:这个应用程序是一个Java 6应用程序的集合,实现为OSGi包,并使用Maven 2.2.1编译/执行.使用任何特定的开发IDE都没有要求.该系统正在Microsoft Windows XP环境中进行测试,但也有计划在其他环境中执行此系统(因此首选跨平台解决方案).
确保所需关系的最简单方法是通过限制蓝图模式类型来派生子集模式的类型。不过,听起来那艘船似乎已经起航了。
和这里的其他人一样,我不知道有任何工具可以开箱即用地执行此操作(尽管如果 Petru Gardea 说 QT Assistant 可以,那么值得跟进)。
一个复杂之处在于,有两种不同的方式来查看要验证的子集/超集关系:(1) 模式 1 接受为有效的每个文档(或元素)也被模式 2 接受为有效(不参考类型)所做的分配),或(2)针对模式 1 和 2 通过验证(规范中称为后模式验证信息集)生成的类型化文档彼此之间存在适当的关系:如果元素或属性在树1,在树2中有效;树 1 中分配给它的类型是树 2 中分配给它的类型的限制;等等。如果模式 1 和模式 2 是独立开发的,那么它们的类型通过派生相关的可能性很小,所以我想您心中已经想到了解决该问题的第一种方法。
不过,无论哪种形式,这个问题都是绝对可以解决的。对于任何模式(我仔细使用这个术语),根据定义,都声明了有限数量的类型和有限数量的元素名称;由此可见,元素名称/类型对的数量是有限的(可能很大)。
该算法可以是这样的。
从预期的根元素开始。(如果有多个可能的根元素,那么在一般情况下,您需要对每个根元素运行此检查。)如果预期的根元素是 E,在模式 1 中类型为 T1,在模式 2 中类型为 T2,则将任务“比较类型 T1 和 T2”放入打开任务队列中。已完成的任务列表将为空。
比较两个复杂类型 T1 和 T2:
检查为 T1 和 T2 声明的属性集,了解其名称之间的子集/超集关系。确保预期超集中所需的属性在预期子集中不存在或可选。
为 T1 和 T2 声明的每个属性 A 都将被分配一个类型(称为 ST1 和 ST2)。如果 ST1 = ST2,则不执行任何操作;否则,将任务“比较简单类型 ST1 和 ST2”添加到打开任务队列中,除非它位于已完成的比较列表中。
现在检查 T1 和 T2 中可能的子级序列——正如 13ren 在评论中建议的那样,这很容易处理,因为内容模型本质上是使用元素名称集作为字母表的正则表达式;因此,它们定义的语言是常规的,并且子集/超集关系对于常规语言是可确定的。
每个可能的子元素 C 都由父类型 T1 和 T2 分配了元素声明和类型定义。我们将它们称为 ED1、ED2、CT1 和 CT2。每个同名的子元素都具有相同的类型,但不同的子元素可能匹配不同的元素声明。因此,对于任何可能的名称,只会有一对类型 CT1 和 CT2,但可能有多对 ED1 和 ED2(并且分析需要小心以确保它们正确匹配;这可能很难自动化)。
如果 CT1 = CT2,则不执行任何操作,否则将“比较类型 CT1 和 CT2”放入打开的任务队列中,除非已执行比较。
如果 ED1 和 ED2 结构相同,则不执行任何操作;否则将比较它们的任务放入任务队列中(除非它已经完成)。
要比较两个简单类型 ST1 和 ST2,请比较它们的词法空间(如果您想要模式上子集/超集关系的第一个定义)或它们的值空间(如果您想要第二个)。如果 ST1 和 ST2 都是同一基元类型的限制,您也许可以轻松比较它们的有效的基于方面的限制集。模式方面可能会使事情变得复杂,但因为它定义了一组正则表达式,所以子集/超集关系对于它来说是可判定的。
要比较两个元素声明,您需要比较元素声明的每个属性并检查所需的子集/超集关系。
正如您所看到的,它足够复杂和乏味,以至于您确实希望自动执行此分析,而且它也足够复杂,因此很容易看出为什么它没有作为开箱即用功能广泛提供。但编码肯定会很有趣。