要针对多个 xsd 模式验证 XML

Posted

技术标签:

【中文标题】要针对多个 xsd 模式验证 XML【英文标题】:XML to be validated against multiple xsd schemas 【发布时间】:2011-02-07 03:51:39 【问题描述】:

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

我想要一个上传工具,可以根据 xml 文件向我的应用程序添加内容。 xml 文件的一部分应根据另一部分中的值之一针对不同的模式进行验证。下面举个例子来说明:

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

在这种情况下,&lt;bar&gt; 的内容有一些受控词汇,我可以很好地处理这部分。然后,根据 bar 值,应使用适当的 xml 模式来验证 bar-config 的内容。对于 baz 和 baz-config 也是如此。

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

理想情况下,该解决方案将允许 xml 作者声明适当的架构位置和其他内容,以便他/她可以在足够智能的编辑器中动态验证 xml。

另外,&lt;bar&gt;&lt;baz&gt; 的可能值是正交的,所以我不想通过扩展来对每个可能的 bar/baz 组合进行此操作。我的意思是,如果有 24 个可能的 bar 值/模式和 8 个可能的 baz 值/模式,我希望能够编写 1 + 24 + 8 = 33 个总模式,而不是 1 * 24 * 8 = 192 个总模式.

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

【问题讨论】:

【参考方案1】:

我终于明白了。

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

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

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

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

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

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

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

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

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

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

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

    仅使用主 (foo) 架构验证 xml 确定用于验证文档部分的架构 使用单独的架构查找作为要验证的部分的根节点 将该节点导入到一个全新的文档中 使用其他架构文件验证全新文档

注意事项:似乎必须构建可识别命名空间的文档才能使其正常工作。

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

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

【讨论】:

它对我不起作用。解决方案->***.com/questions/61483586/…【参考方案2】:

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

它旨在做您想做的事情(验证 XML 文档中具有自己的命名空间和架构的部分)。

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

希望对您有所帮助! 凯文

【讨论】:

如果你的模式是不同的类型(XSD、RNG 和 DTD),这也很好【参考方案3】:

您需要为实例文档的每个单独验证的部分定义一个目标命名空间。然后定义一个master schema,它使用&lt;xsd:include&gt; 来引用这些组件的架构文档。

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

【讨论】:

【参考方案4】:

您还可以使用“资源解析器”来允许“xml 作者”指定他们自己的架构文件,至少在某种程度上,例如:https://***.com/a/41225329/32453 归根结底,您想要一个完全兼容的 xml 文件无论如何,这可以使用普通工具进行验证:)

【讨论】:

以上是关于要针对多个 xsd 模式验证 XML的主要内容,如果未能解决你的问题,请参考以下文章

针对同一 XML 模式 (XSD) 加快一批 XML 文件的 XML 模式验证

在 C# 中针对 XSD 模式验证 json 数据

针对XML模式的通用XML文件验证器(XSD文件)

使用C#导入使用XSD验证XML

XML的验证模式DTD与XSD的区别

验证 XSD 架构?