解析XML文件并保留有关行号的信息
我正在创建一个工具来分析一些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
就已经定义了startAttribute
和startElementBeforeReadingAttributes
方法,我不会有任何这里的问题:O)
所以我的问题是我怎么能解决我的问题?
有关信息,我使用的Java 6
PS:也许另一个标题为这个问题可能是Java的SAX与属性解析事件,或类似的东西解析...
我认为只有实现这一点的方法是创建自己的InputStream(或Reader)来计算行数并以某种方式与SAX处理程序进行通信。我没有试图自己实现这一点,但我相信这是可能的。我祝你好运,并会很高兴,如果你成功做到这一点,并在这里发布你的结果。
寻找一个开源的XML编辑器,它的解析器可能有这个信息。
编辑器不使用相同类型的解析器,只是使用xml数据的应用程序将使用该解析器。编辑需要更多的信息,就像你说的行号一样,我也会考虑有关空白字符的信息。编辑器的解析器不应该丢失有关文件中字符的任何信息。这就是你可以实现格式化函数或“选择封闭元素”(Eclipse中的Alt-Shift-Up)的方式。
在XmlBeans和JAXB中都可以保留行号信息。你可以考虑使用这些工具之一(在XmlBeans中更容易)。
鉴于定位器界面的描述,您正在观察的行为有些有效。 getLineNumber()方法返回一个近似值,而不是绝对值。 – 2010-12-03 09:09:17