2

我已经看到了多个与使用woodstox 和JAXB 解析xml 以使用XMLStreamReader和验证模式解组相关的问题。尽管阅读它们并没有帮助。我需要的是使用本地 DTD 验证传入的 xml 并将整个内容解析为对象表示。传入的 xml 可以有一个包含 DTD 的 DOCTYPE。这需要跳过,而需要使用本地 DTD。实施应该非常快。预计 < 1ms 进行验证和解析。我可以在 5 毫秒内使用以下内容单独解析。合并验证不适用于设置架构(注释的代码行)

xmlif = XMLInputFactory2.newInstance();
    xmlif.setProperty(XMLInputFactory2.SUPPORT_DTD, false);
    JAXBContext ucontext;
    ucontext = JAXBContext.newInstance(XMLOuterElementClass.class);
    unmarshaller = ucontext.createUnmarshaller();
    /*SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.XML_DTD_NS_URI);
    Schema schema = sf.newSchema(new File("c:/resources/schma.dtd"));
    unmarshaller.setSchema(schema);*/

XMLStreamReader xsr = xmlif
                .createXMLStreamReader(new StringReader(xml));
        //xsr = new StreamReaderDelegate(xsr);
        long start = System.currentTimeMillis();

        try {
            while (xsr.hasNext()) {
                if (xsr.isStartElement()
                        && xsr.getLocalName() == "XMLOuterElementClass") {
                    break;
                }
                xsr.next();
            }
            JAXBElement<XMLOuterElementClass> jb = unmarshaller.unmarshal(xsr,
                XMLOuterElementClass.class);
            System.out.println("Total time taken in ms :" + (end - start));

        } finally {
            xsr.close();
        }
4

1 回答 1

3

有多种方法可以做到这一点;获得更深入答案的最佳方法是在 Woodstox 用户列表上询问此问题(请参阅http://xircles.codehaus.org/projects/woodstox/lists)。

但需要注意的一点是,JAXB 对 Stax2(Woodstox/Aalto 对基本 Stax 的扩展)一无所知,因此您需要通过 Stax2 API 而不是 JAXB 来访问它。因此,要启用“外部”验证,您需要调用:

xmlStreamReader2.validateAgainst(schemaFromDTD);

并且您可以在构建流阅读器之后立即执行此操作(需要转换为XMLStreamReader2,或至少转换为Validatable)。请注意,您可以在读取或写入时进行验证,两者的工作方式相似(在后一种情况下,您可以通过 启用它XMLStreamWriter)。

另一种可能性是定义XMLResolver属性(参见 参考资料XMLInputFactory.RESOLVER)。它在尝试读取外部 dtd 时被调用,也就是说,当 DOCTYPE 包含对外部文件的引用时。然后自定义XMLResolver可以重定向此读取以使用其他来源。

请注意,第一种方法(您开始使用的方法)可能更有效,因为它只需要读取和解析 Schema 一次,假设您读取一次并在之后重用。验证本身应该很快,如果解析需要 4 毫秒,则不应超过 1 毫秒;特别是如果您在 4 毫秒内包含 JAXB 处理(这在技术上是数据绑定,高于较低级别的解析)。

于 2013-08-21T17:02:02.117 回答