要针对多个xsd架构validation的XML

我正在编写xsd和validation代码,所以我在这里有很好的控制权。

我想有一个上传工具,可以根据xml文件向我的应用程序添加内容。 应根据其他部分中的一个值,针对不同的模式validationxml文件的一部分。 这是一个例子来说明:

 Harold Alpha Mercury         

在这种情况下, 的内容有一些受控的词汇表,我可以很好地处理那部分。 然后,根据条形值,应使用适当的xml架构来validationbar-config的内容。 同样适用于baz和baz-config。

执行解析/validation的代码是用Java编写的。 不确定解决方案将依赖于语言。

理想情况下,该解决方案将允许xml作者声明适当的架构位置以及什么不是,以便他/她可以在足够智能的编辑器中动态validationxml。

此外, 的可能值是正交的,因此我不希望通过扩展为每个可能的bar / baz组合执行此操作。 我的意思是,如果有24个可能的条形值/模式和8个可能的baz值/模式,我希望能够写出1 + 24 + 8 = 33个总模式,而不是1 * 24 * 8 = 192个模式。

此外,如果可能的话,我宁愿不将bar-config和baz-config分解为单独的xml文件。 我意识到可能会使所有问题变得更容易,因为每个xml文件都有一个模式,但我正在尝试查看是否有一个好的单xml文件解决方案。

我终于想通了。

首先,在foo架构中,bar-config和baz-config元素的类型包含any元素,如下所示:

    

在xml中,您必须使用bar-config或baz-config的子元素上的xmlns属性指定正确的命名空间,如下所示:

   ... config xml here ...   

然后,条形Alpha的XML模式文件将具有http://www.example.org/bar/Alpha的目标名称空间,并将定义根元素config

如果您的XML文件具有两个模式文件的名称空间声明和模式位置,那么编辑器就可以完成所有validation(至少对Eclipse来说足够好)。

到目前为止,我们已经满足了xml作者可能以在编辑器中validation它的方式编写xml的要求。

现在,我们需要消费者能够validation。 就我而言,我正在使用Java。

如果有可能,您知道需要用于提前validation的模式文件,那么您只需创建一个Schema对象并像往常一样进行validation,如下所示:

 Schema schema = factory().newSchema(new Source[] { new StreamSource(stream("foo.xsd")), new StreamSource(stream("Alpha.xsd")), new StreamSource(stream("Mercury.xsd")), }); 

但是,在这种情况下,在解析主文档之前,我们不知道要使用哪些xsd文件。 因此,一般程序是:

  1. 仅使用main(foo)模式validationxml
  2. 确定用于validation文档部分的架构
  3. 使用单独的模式查找要validation的部分的根节点
  4. 将该节点导入到一个全新的文档中
  5. 使用其他模式文件validation全新文档

警告:似乎必须构建文档名称空间才能使其正常工作。

这是一些代码(这是从我的代码的各个地方撕掉的,因此复制和粘贴可能会引入一些错误):

 // Contains the filename of the xml file String filename; // Load the xml data using a namespace-aware builder (the method // 'stream' simply opens an input stream on a file) Document document; DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilderFactory.setNamespaceAware(true); document = docBuilderFactory.newDocumentBuilder().parse(stream(filename)); // Create the schema factory SchemaFactory sFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI); // Load the main schema Schema schema = sFactory.newSchema( new StreamSource(stream("foo.xsd"))); // Validate using main schema schema.newValidator().validate(new DOMSource(document)); // Get the node that is the root for the portion you want to validate // using another schema Node node= getSpecialNode(document); // Build a Document from that node Document subDocument = docBuilderFactory.newDocumentBuilder().newDocument(); subDocument.appendChild(subDocument.importNode(node, true)); // Determine the schema to use using your own logic Schema subSchema = parseAndDetermineSchema(document); // Validate using other schema subSchema.newValidator().validate(new DOMSource(subDocument)); 

看看NVDL(基于命名空间的validation调度语言) – http://www.nvdl.org/

它旨在执行您想要执行的操作(validation具有自己的命名空间和模式的XML文档的各个部分)。

这里有一个教程 – http://www.dpawson.co.uk/nvdl/ – 这里有一个Java实现 – http://jnvdl.sourceforge.net/

希望有所帮助! 凯文

您需要为实例文档的每个单独validation的部分定义目标命名空间。 然后定义一个主模式 ,该模式使用来引用这些组件的模式文档。

这种方法的局限性在于您不能让各个组件定义应该用于validation它们的模式。 但是一般来说,让文档告诉你如何validation它是一个坏主意(即validation应该是你的应用程序控制的东西)。