解析XML文件,同时保留有关行号的信息

时间:2010-12-03 08:55:47

标签: java sax xml-parsing

我正在创建一个分析某些XML文件(XHTML文件的工具)。此工具的目的不仅是验证XML结构,还要检查某些属性的值。

所以我创建了自己的org.xml.sax.helpers.DefaultHandler来处理XML解析期间的事件。我的一个要求是获得有关当前行号的信息。所以我决定将org.xml.sax.helpers.LocatorImpl添加到我自己的DefaultHandler。除了关于XML属性的问题之外,这几乎解决了我的所有问题。

我们举一个例子:

<rootNode>
    <foo att1="val1"/>
    <bar att2="val2"
         answerToEverything="43"
         att3="val3"/>
</rootNode>

我的一条规则表明,如果在节点answerToEverything上定义属性bar,则其值不应与42不同。

遇到这样的XML时,我的工具应该检测到错误。因为我想向用户提供精确的错误消息,例如:

  

文件“foo.xhtml”第4行出错:answerToEverything只允许“42”作为值。

我的解析器必须能够在解析期间保留行号,甚至是属性。如果我们考虑自己的DefaultHandler类的以下实现:

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    System.out.println("Start element <" + qName + ">" + x());
    for (int i = 0; i < attributes.getLength(); i++) {
        System.out.println("Att '" + attributes.getQName(i) + "' = '" + attributes.getValue(i) + "' at " + locator.getLineNumber() + ":" + locator.getColumnNumber());
    }
}

然后对于节点>bar>,它将显示以下输出:

  

在5:23开始元素   在5:23左右'att2'='val2'   在5:23左右''toToEverything'='43'   在5点23分'att3'='val3'

如您所见,行号是错误的,因为解析器将考虑整个节点,包括其属性作为一个块。

理想情况下,如果界面ContentHandler已经定义了startAttributestartElementBeforeReadingAttributes方法,我在这里就不会有任何问题:o)

所以我的问题是如何解决我的问题?

有关信息,我使用的是Java 6

ps:也许这个问题的另一个标题可能是使用解析事件的属性进行Java SAX解析,或类似的东西......

3 个答案:

答案 0 :(得分:0)

我认为实现这一点的唯一方法是创建自己的InputStream(或Reader)来计算行数并以某种方式与SAX处理程序进行通信。我自己没有尝试过这个,但我相信这是可能的。祝你好运,如果你成功做到这一点并在这里发布你的结果会很高兴。

答案 1 :(得分:0)

寻找开源XML编辑器,其解析器可能包含此信息。

编辑器不使用与仅使用xml进行数据的应用程序相同的解析器。编辑需要更多的信息,就像你说的行号,我也会想到有关空白字符的信息。编辑器的解析器不应丢失有关文件中字符的任何信息。这就是你可以实现的方式,例如格式化函数或“选择封闭元素”(Eclipse中的Alt-Shift-Up)。

答案 2 :(得分:0)

在XmlBeans和JAXB中都可以保留行号信息。您可以考虑使用这些工具之一(在XmlBeans中更容易)。