【问题标题】:Validate and parse xml using woodstox with local dtd使用带有本地 dtd 的 woodstox 验证和解析 xml
【发布时间】:2013-08-23 14:22:22
【问题描述】:

我看到了多个与使用woodstox 和JAXB 解析xml 以使用XMLStreamReader 解组并针对模式进行验证有关的问题。尽管阅读它们并没有帮助。我需要的是使用本地 DTD 验证传入的 xml 并将整个内容解析为对象表示。传入的 xml 可以有一个包含 DTD 的 DOCTYPE。这需要跳过,而需要使用本地 DTD。实施应该非常快。预计

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】:

    有多种方法可以做到这一点;获得更深入答案的最佳方法是在 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 处理(这在技术上是数据绑定,高于较低级别的解析)。

    【讨论】:

    • 感谢您的指点。将尝试用户列表。将验证和解析时间缩短到
    • 真的取决于内容的大小; XML 的解析可以以每秒 10-40 兆字节的速度完成,具体取决于解析器。所以在 1ms 内,应该可以做 10-40kB 的文档。但是 JAXB 开销问题更大。还要确保总是重用XMLInputFactory
    • 嗯,这给了尝试的希望。如果我在预期的时间范围内成功验证和解析,我将分享我的发现。此外,当您说可以在 1 毫秒内解析时,期望它解析整个内容,而不仅仅是您感兴趣的部分。
    • 正确;解析整个内容——即使跳过,解析器也必须完成大部分工作(验证格式正确,如名称有效性、属性名称唯一性、嵌套、实体扩展)。
    • 只是想更新一下,woodstox 确实带来了预期的结果,对于上述作为比赛一部分的问题陈述,我们最终获得了第一名 :)
    猜你喜欢
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 2015-12-17
    相关资源
    最近更新 更多