我终于明白了。
首先,在 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));