使用Xerces SAX解析器读取错误标记时,不会报告DTD错误

时间:2012-08-14 07:36:55

标签: java xml dtd saxparser xerces

我正在尝试使用Apache Xerces SAX2验证解析器来解析和验证一个非常简单的XML文件。 DTD是从XML文件引用的,我的简单实体解析器可以成功返回DTD文件的正确InputStream。 我有一个非常基本的标签结构,它与命名它们无关,所以我只是给XML标签写了一封信。 主标签是A,A标签内可能有零个或多个B,但只有B的。 B中有零个或多个C。 所以适当的XML将是:

<A>
<B><C>somecharacters</C></B>
</A>

我创建了一些单元测试并且遇到了一种奇怪的行为。我想如果我给上面的解析器提供类似的XML,但只有C的结束标记没有匹配的开始标记而没有父元素B,解析器将报告DTD验证错误。 这是根据DTD的故意无效的XML示例:

<A>
<C>somecharacters</C></B>
</A>

很明显,这个XML片段格式不正确。 不幸的是(或者我对SAX解析器不了解)解析器调用ContentHandler的C标签的startElement方法,然后调用C标签内的字符的字符方法。 DTD明确指出A标签只能有B标签作为子标签,而不是C标签,因为C首先需要嵌套在B内。 我不明白的是为什么解析器在意识到嵌套的C不在一个好地方之后调用了字符方法

我在ContentHandler方法中的应用程序逻辑依赖于根据DTD嵌套标签的假设,我不想用null-checker和错误处理代码填充这3个方法,因为我认为这是DTD验证器的工作

我设置解析器的代码是(异常处理部分不相关):

    private static final String VALIDATION_FEATURE = "http://xml.org/sax/features/validation";
    private static final String SAX_PARSER_IMPLEMENTATION = "org.apache.xerces.parsers.SAXParser";
    ......
    XMLReader parser = XMLReaderFactory.createXMLReader(SAX_PARSER_IMPLEMENTATION);
    parser.setFeature(VALIDATION_FEATURE, true);
    parser.setErrorHandler(new CustomErrorHandler());
    parser.setEntityResolver(entityResolver);
    parser.setContentHandler(handler);

    InputSource inputSource = new InputSource(stream);
    try {
        parser.parse(inputSource);
    } catch (IOException e) {
        throw new ControlFileReadException("Error while parsing the control file.", e);
    } catch (SAXException e) {
        if (e.getCause() instanceof IncorrectCounterNameException) {
            throw new IncorrectCounterNameException(e.getCause());
        } else {
            throw e;
        }
    }

    private final class CustomErrorHandler implements ErrorHandler {
    public void warning(SAXParseException spe) throws SAXException {
        throw spe;
    }

    public void fatalError(SAXParseException spe) throws SAXException {
        throw spe;
    }

    public void error(SAXParseException spe) throws SAXException {
        throw spe;
    }
}

感谢任何帮助!

0 个答案:

没有答案