使用 woodstox 和本地 dtd 验证和解析 xml

问题描述 投票:0回答:1

我看到了多个与使用 woodstox 和 JAXB 解析 xml 相关的问题,以使用

XMLStreamReader
解组并根据模式进行验证。尽管阅读它们并没有帮助。我需要的是使用本地 DTD 验证传入的 xml,并将整个内容解析为对象表示形式。传入的 xml 可以具有包含 DTD 的 DOCTYPE。这需要被跳过并需要使用本地 DTD。实施应该非常快。预计< 1ms to do the validation and parsing. I could manage to parse alone using the following in 5ms. Incorporating validation doesn't work with setting the schema (commented lines of code)

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();
        }
java xml-parsing jaxb stax woodstox
1个回答
3
投票

有多种方法可以实现;获得更深入答案的最佳方法是在 Woodstox 用户列表上询问(请参阅 https://groups.google.com/g/woodstox-user)。

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

xmlStreamReader2.validateAgainst(schemaFromDTD);

您可以在构建流读取器后立即执行此操作(需要转换为

XMLStreamReader2
,或至少转换为
Validatable
)。 请注意,您可以在读取或写入时进行验证,两者的工作原理类似(在后一种情况下,您可以通过
XMLStreamWriter
启用它)。

另一种可能性是定义

XMLResolver
属性(参见
XMLInputFactory.RESOLVER
)。 当尝试读取外部 dtd 时,即当 DOCTYPE 包含对外部文件的引用时,它会被调用。然后,自定义
XMLResolver
可以重定向此读取以使用其他来源。

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

© www.soinside.com 2019 - 2024. All rights reserved.