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

时间:2013-08-21 09:21:58

标签: java xml-parsing jaxb stax woodstox

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

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();
        }

1 个答案:

答案 0 :(得分:3)

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

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

xmlStreamReader2.validateAgainst(schemaFromDTD);

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

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

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