2010-12-03 80 views
3

我正在创建一个工具来分析一些XML文件(准确地说是XHTML文件)。此工具的目的不仅在于验证XML结构,还用于检查某些属性的值。解析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
ATT“ATT2” = 'val2的' 在5:23
ATT 'answerToEverything'= '43' 在5:23
ATT 'ATT3'= 'VAL3' 在5:23

正如你所看到的,行号是错误的,因为解析器会考虑整个节点,包括它的属性作为一个块。

理想的情况下,如果接口ContentHandler就已经定义了startAttributestartElementBeforeReadingAttributes方法,我不会有任何这里的问题:O)

所以我的问题是我怎么能解决我的问题?

有关信息,我使用的Java 6

PS:也许另一个标题为这个问题可能是Java的SAX与属性解析事件,或类似的东西解析...

+0

鉴于定位器界面的描述,您正在观察的行为有些有效。 getLineNumber()方法返回一个近似值,而不是绝对值。 – 2010-12-03 09:09:17

回答

0

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

0

寻找一个开源的XML编辑器,它的解析器可能有这个信息。

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

0

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