【问题标题】:Is it possible to get the current line number when parsing an XML document with Xerces?使用 Xerces 解析 XML 文档时是否可以获得当前行号?
【发布时间】:2010-10-08 21:15:09
【问题描述】:

我有一个使用 xerces API 解析 XML 文档的 java 程序。

我的解析类扩展了 org.apache.xerces.parsers.XMLDocumentParser,重载了 startElement、endElement、characters 方法。

由于是手工编写的复杂XML文档(主要是某种配置元素),经典的xsd或dtd验证是不够的,还得向用户回馈XML文档无效。

但我无法实现的一件事是在错误消息中添加有关当前正在解析的行号(以及为什么不包含列号)以及错误发生位置的信息。

我认为这是可能的,因为当 XML 文档不是 XML 有效时解析器生成的异常 (org.apache.xerces.xni.parser.XMLParseException) 包含这些信息。

【问题讨论】:

    标签: java xml xerces line-numbers


    【解决方案1】:

    我从来没有用 xerces 尝试过,但是 SAX 解析器可以存储一个 SAX Locator,您可以在解析文档时(或在异常之后)从中获取行号和列号。

    看起来XMLDocumentParser 可以做同样的事情。它的父类AbstractXMLDocumentParser 有一个startDocument 方法,该方法传递了一个XMLLocator 参数。如果重写此方法,则可以保存 XMLLocator 并使用其 getLineNumbergetColumnNumber 方法。

    【讨论】:

    • 覆盖 startDocument 方法是在我的情况下完美工作的方法,谢谢
    【解决方案2】:

    不确定“正确”的方式是什么,但查看 API,假设您提供的 XMLInputSource 采用 InputStream 或 Reader,您可以在 InputStream/Reader 中提供,该 InputStream/Reader 用 LineNumberInputStream 或 LineNumberReader 包装,然后查询它行号。

    例如:

    输入流; 流 = ...; 新的 XMLInputSource(流);

    会变成:

    输入流; LineNumberInputStream 线流; 流 = ...; lineStream = new LineNumberInputStream(lineStream); 新的 XMLInputSource(lineStream); // 现在可以通过 getLineNumber() 询问线路流它在哪一行

    我猜你还需要将 LineNumberInputStream/LineNumberReader 传递给扩展 XMLDocumentParser 的类。

    不确定所有这些在您的代码中是否可行。

    或者深入研究源代码并找出他们是如何做到的。如果您需要访问的变量/方法是私有的,并且您不担心将来会破坏代码,则可以使用反射并删除访问权限来获取它。

    【讨论】:

    • 如果 API 无法实现,您的解决方案是我想到的。我很高兴我不必这样做:-),但谢谢
    • 这不能保证有效。确实可能不会。 XML 解析器很可能已经读取了多行,然后才费心报告文档中的任何信息。事实上,一个标签可以跨越多行。 LineNumberReader 可能没有定位在它需要在那里才能工作的地方。 :-(
    猜你喜欢
    • 2013-07-22
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    相关资源
    最近更新 更多