我正在创建一个分析某些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
已经定义了startAttribute
和startElementBeforeReadingAttributes
方法,我在这里就不会有任何问题:o)
所以我的问题是如何解决我的问题?
有关信息,我使用的是Java 6
ps:也许这个问题的另一个标题可能是使用解析事件的属性进行Java SAX解析,或类似的东西......
答案 0 :(得分:0)
我认为实现这一点的唯一方法是创建自己的InputStream(或Reader)来计算行数并以某种方式与SAX处理程序进行通信。我自己没有尝试过这个,但我相信这是可能的。祝你好运,如果你成功做到这一点并在这里发布你的结果会很高兴。
答案 1 :(得分:0)
寻找开源XML编辑器,其解析器可能包含此信息。
编辑器不使用与仅使用xml进行数据的应用程序相同的解析器。编辑需要更多的信息,就像你说的行号,我也会想到有关空白字符的信息。编辑器的解析器不应丢失有关文件中字符的任何信息。这就是你可以实现的方式,例如格式化函数或“选择封闭元素”(Eclipse中的Alt-Shift-Up)。
答案 2 :(得分:0)
在XmlBeans和JAXB中都可以保留行号信息。您可以考虑使用这些工具之一(在XmlBeans中更容易)。