我想有一个上传工具,可以根据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>的内容存在一些受控词汇表,我可以很好地处理该部分.然后,根据条形值,应使用适当的xml架构来验证bar-config的内容.同样适用于baz和baz-config.
执行解析/验证的代码是用Java编写的.不确定解决方案的语言依赖性.
理想情况下,该解决方案将允许xml作者声明适当的模式位置以及什么不是,以便他/她可以在足够智能的编辑器中动态验证xml.
此外,< bar>的可能值.和< baz>是正交的,所以我不希望通过扩展为每个可能的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元素,如下所示:
<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>
然后,条形Alpha的XML模式文件将具有http://www.example.org/bar/Alpha的目标名称空间,并将定义根元素配置.
如果您的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文件.因此,一般程序是:
>仅使用main(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));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。