有没有一种方法可以通过SAX / DOM解析XML,并且每个节点都有可用的行号 - java

我已经为大型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:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…