gpt4 book ai didi

java - 要针对多个 xsd 模式验证的 XML

转载 作者:数据小太阳 更新时间:2023-10-29 02:02:38 25 4
gpt4 key购买 nike

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

我想要一个上传工具,可以根据 xml 文件向我的应用程序添加内容。应该根据 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>

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

执行解析/验证的代码是用 Java 编写的。不确定解决方案对语言的依赖程度如何。

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

此外,<bar> 的可能值和 <baz>是正交的,所以我不想通过扩展每个可能的 bar/baz 组合来做到这一点。我的意思是,如果有 24 个可能的 bar 值/模式和 8 个可能的 baz 值/模式,我希望能够编写 1 + 24 + 8 = 33 个模式,而不是 1 * 24 * 8 = 192 个模式.

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

最佳答案

我终于明白了。

首先,在 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 文件。因此,一般程序是:

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

警告:看来文档必须构建为命名空间感知才能使其工作。

这是一些代码(这是从我的代码的不同地方截取的,因此复制和粘贴可能会引入一些错误):

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

关于java - 要针对多个 xsd 模式验证的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2624763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com