我已经为大型XML文档格式编写了DOM解析器,其中包含许多可用于自动生成Java代码的项目。这仅限于小表达式,然后将其合并到动态生成的Java源文件中。
到目前为止,一切都很好。一切正常。
但是-我希望能够嵌入包含Java代码的XML节点的行号(因此,如果配置中包含不可编译的代码,则每种方法都将具有一个指向源XML文档的指针和行号,以简化操作调试)。我在解析时不需要行号,也不需要验证XML Source Document并在特定行号上抛出错误。我需要能够访问DOM或每个SAX事件中每个节点和属性的行号。
关于如何实现这一目标的任何建议?
附言
另外,我读到StAX有一种在解析时获取行号的方法,但是理想情况下,我希望通过Java 4/5中的常规SAX / DOM处理获得相同的结果,而不是成为Java 6+应用程序或承担额外的费用。 jar文件。
参考方案
我知道这个线程有点旧(抱歉),但是花了我这么长时间才能破解这个螺母,我不得不与某人分享解决方案...
您似乎只能使用不构建DOM的SAX获得行号。 DOM解析器不提供行号,也不能让您靠近它正在使用的SAX解析器。我的解决方案是使用SAX源和DOM结果进行空的XSLT转换,但是即使那样,也有人会尽力将其隐藏起来。请参见下面的代码。
我使用自己的名称空间将位置信息作为属性添加到每个元素,因此可以使用XPath查找元素并报告数据的来源。
希望这可以帮助:
// The file to parse.
String systemId = "myxml.xml";
/*
* Create transformer SAX source that adds current element position to
* the element as attributes.
*/
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
LocationFilter locationFilter = new LocationFilter(xmlReader);
InputSource inputSource = new InputSource(new FileReader(systemId));
// Do this so that XPath function document() can take relative URI.
inputSource.setSystemId(systemId);
SAXSource saxSource = new SAXSource(locationFilter, inputSource);
/*
* Perform an empty transformation from SAX source to DOM result.
*/
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMResult domResult = new DOMResult();
transformer.transform(saxSource, domResult);
Node root = domResult.getNode();
...
class LocationFilter extends XMLFilterImpl {
LocationFilter(XMLReader xmlReader) {
super(xmlReader);
}
private Locator locator = null;
@Override
public void setDocumentLocator(Locator locator) {
super.setDocumentLocator(locator);
this.locator = locator;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// Add extra attribute to elements to hold location
String location = locator.getSystemId() + ':' + locator.getLineNumber() + ':' + locator.getColumnNumber();
Attributes2Impl attrs = new Attributes2Impl(attributes);
attrs.addAttribute("http://myNamespace", "location", "myns:location", "CDATA", location);
super.startElement(uri, localName, qName, attrs);
}
}
Java:正则表达式模式匹配器是否有大小限制? - java我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)
Java:线程池如何将线程映射到可运行对象 - java试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …
JAVA:字节码和二进制有什么区别? - javajava字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…
java:继承 - java有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…
Java:BigInteger,如何通过OutputStream编写它 - java我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…