要针对多个xsd架构验证的XML [英] XML to be validated against multiple xsd schemas

查看:191
本文介绍了要针对多个xsd架构验证的XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing the xsd and the code to validate, so I have great control here.

我想有一个上传工具,可以添加东西给我基于xml文件的应用程序。应根据其他部分中的一个值,针对不同的模式验证xml文件的一部分。以下是一个示例:

I would like to have an upload facility that adds stuff to my application based on an xml file. One part of the xml file should be validated against different schemas based on one of the values in the other part of it. Here's an example to illustrate:

<foo>
  <name>Harold</name>
  <bar>Alpha</bar>
  <baz>Mercury</baz>
  <!-- ... more general info that applies to all foos ... -->

  <bar-config>
    <!-- the content here is specific to the bar named "Alpha" -->
  </bar-config>
  <baz-config>
    <!-- the content here is specific to the baz named "Mercury" -->
  </baz>
</foo>

在这种情况下,的内容有一些受控词汇表< bar> ,我可以处理那部分就好了。然后,根据条形值,应使用适当的xml架构来验证bar-config的内容。类似地,对于baz和baz-config。

In this case, there is some controlled vocabulary for the content of <bar>, and I can handle that part just fine. Then, based on the bar value, the appropriate xml schema should be used to validate the content of bar-config. Similarly for baz and baz-config.

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

The code doing the parsing/validation is written in Java. Not sure how language-dependent the solution will be.

理想情况下,解决方案将允许xml作者声明相应的架构位置以及什么不是,以便他/她可以在一个足够聪明的编辑器中动态验证xml。

Ideally, the solution would permit the xml author to declare the appropriate schema locations and what-not so that s/he could get the xml validated on the fly in a sufficiently smart editor.

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

Also, the possible values for <bar> and <baz> are orthogonal, so I don't want to do this by extension for every possible bar/baz combo. What I mean is, if there are 24 possible bar values/schemas and 8 possible baz values/schemas, I want to be able to write 1 + 24 + 8 = 33 total schemas, instead of 1 * 24 * 8 = 192 total schemas.

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

Also, I'd prefer to NOT break out the bar-config and baz-config into separate xml files if possible. I realize that might make all the problems much easier, as each xml file would have a single schema, but I'm trying to see if there is a good single-xml-file solution.

推荐答案

我终于弄明白了。

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

First of all, in the foo schema, the bar-config and baz-config elements have a type which includes an any element, like this:

<sequence>
    <any minOccurs="0" maxOccurs="1"
        processContents="lax" namespace="##any" />
</sequence>

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

In the xml, then, you must specify the proper namespace using the xmlns attribute on the child element of bar-config or baz-config, like this:

<bar-config>
    <config xmlns="http://www.example.org/bar/Alpha">
        ... config xml here ...
    </config>
</bar-config>

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

Then, your XML schema file for bar Alpha will have a target namespace of http://www.example.org/bar/Alpha and will define the root element config.

如果您的XML文件具有两个模式文件的名称空间声明和模式位置,则编辑器可以执行所有操作验证(至少对Eclipse来说足够好)。

If your XML file has namespace declarations and schema locations for both of the schema files, this is sufficient for the editor to do all of the validating (at least good enough for Eclipse).

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

So far, we have satisfied the requirement that the xml author may write the xml in such a way that it is validated in the editor.

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

Now, we need the consumer to be able to validate. In my case, I'm using Java.

如果有可能,您知道需要提前验证的架构文件,那么您只需创建一个Schema对象并照常验证,如下所示:

If by some chance, you know the schema files that you will need to use to validate ahead of time, then you simply create a single Schema object and validate as usual, like this:

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

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

In this case, however, we don't know which xsd files to use until we have parsed the main document. So, the general procedure is to:


  1. 仅使用main(foo)架构验证xml

  2. 确定用于验证文档部分的模式

  3. 使用单独的模式查找要验证的部分的根节点

  4. 将该节点导入全新文档

  5. 使用其他模式文件验证全新文档

  1. Validate the xml using only the main (foo) schema
  2. Determine the schema to use to validate the portion of the document
  3. Find the node that is the root of the portion to validate using a separate schema
  4. Import that node into a brand new document
  5. Validate the brand new document using the other schema file

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

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

Here's some code (this was ripped from various places of my code, so there might be some errors introduced by the copy-and-paste):

// 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));

这篇关于要针对多个xsd架构验证的XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆