从 xml 节点获取行号 - java

2024-04-22

我已经解析了一个 XML 文件并获得了一个我感兴趣的节点。现在如何在源 XML 文件中找到该节点出现的行号?

编辑: 目前我正在使用 SAXParser 来解析我的 XML。不过,我会对使用任何解析器的解决方案感到满意。

除了节点之外,我还有节点的 XPath 表达式。

我需要获取行号,因为我在文本框中显示 XML 文件,并且需要突出显示节点出现的行。假设 XML 文件的格式良好并具有足够的换行符。


我通过以下示例完成了这项工作:

http://eyalsch.wordpress.com/2010/11/30/xml-dom-2/ http://eyalsch.wordpress.com/2010/11/30/xml-dom-2/

该解决方案遵循 Michael Kay 建议的方法。以下是使用方法:

// XmlTest.java

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class XmlTest {
    public static void main(final String[] args) throws Exception {

        String xmlString = "<foo>\n"
                         + "    <bar>\n"
                         + "        <moo>Hello World!</moo>\n"
                         + "    </bar>\n"
                         + "</foo>";

        InputStream is = new ByteArrayInputStream(xmlString.getBytes());
        Document doc = PositionalXMLReader.readXML(is);
        is.close();

        Node node = doc.getElementsByTagName("moo").item(0);

        System.out.println("Line number: " + node.getUserData("lineNumber"));
    }
}

如果运行该程序,它将输出:“行号:3”

PositionalXMLReader 是上面链接的示例的稍微修改的版本。

// PositionalXMLReader.java

import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class PositionalXMLReader {
    final static String LINE_NUMBER_KEY_NAME = "lineNumber";

    public static Document readXML(final InputStream is) throws IOException, SAXException {
        final Document doc;
        SAXParser parser;
        try {
            final SAXParserFactory factory = SAXParserFactory.newInstance();
            parser = factory.newSAXParser();
            final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            final DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            doc = docBuilder.newDocument();
        } catch (final ParserConfigurationException e) {
            throw new RuntimeException("Can't create SAX parser / DOM builder.", e);
        }

        final Stack<Element> elementStack = new Stack<Element>();
        final StringBuilder textBuffer = new StringBuilder();
        final DefaultHandler handler = new DefaultHandler() {
            private Locator locator;

            @Override
            public void setDocumentLocator(final Locator locator) {
                this.locator = locator; // Save the locator, so that it can be used later for line tracking when traversing nodes.
            }

            @Override
            public void startElement(final String uri, final String localName, final String qName, final Attributes attributes)
                    throws SAXException {
                addTextIfNeeded();
                final Element el = doc.createElement(qName);
                for (int i = 0; i < attributes.getLength(); i++) {
                    el.setAttribute(attributes.getQName(i), attributes.getValue(i));
                }
                el.setUserData(LINE_NUMBER_KEY_NAME, String.valueOf(this.locator.getLineNumber()), null);
                elementStack.push(el);
            }

            @Override
            public void endElement(final String uri, final String localName, final String qName) {
                addTextIfNeeded();
                final Element closedEl = elementStack.pop();
                if (elementStack.isEmpty()) { // Is this the root element?
                    doc.appendChild(closedEl);
                } else {
                    final Element parentEl = elementStack.peek();
                    parentEl.appendChild(closedEl);
                }
            }

            @Override
            public void characters(final char ch[], final int start, final int length) throws SAXException {
                textBuffer.append(ch, start, length);
            }

            // Outputs text accumulated under the current node
            private void addTextIfNeeded() {
                if (textBuffer.length() > 0) {
                    final Element el = elementStack.peek();
                    final Node textNode = doc.createTextNode(textBuffer.toString());
                    el.appendChild(textNode);
                    textBuffer.delete(0, textBuffer.length());
                }
            }
        };
        parser.parse(is, handler);

        return doc;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 xml 节点获取行号 - java 的相关文章

随机推荐

  • 如何在postgreSQL命令中指示在哪个数据库中执行脚本? (类似于SQL Server“use”命令)

    我有以下问题 我需要放入一个在新版本推出之前运行的脚本 该脚本在 PostgreSQL 中启用 pgAgent 的 SQL 代码 但是 此代码应该在维护数据库 postgres 上运行 而我们运行脚本文件的数据库是另一个数据库 我记得在 S
  • 如何检测视频标签上播放的视频的帧速率?

    有什么方法可以通过 javascript 检测视频 html5 标签中引用的视频的帧速率是多少 我还在寻找比特率和编解码器信息 因为 html5 视频播放器与编解码器无关 thanks FPS 存储在video文件的标题 这是您正在寻找的实
  • 使用 Swift array.count 和 arc4random()

    为了让这段代码正常工作 我缺少什么 NodesLeft 是一个 Int let x nodesLeft count let r Int arc4random uniform x 我收到错误 Playground 执行失败 错误 136 40
  • Javascript:在数组末尾重新启动一次循环

    我最近遇到了这个问题 但在任何地方都找不到好的答案 因此有这个问题 我想在到达终点后重新启动循环 但只循环有限的次数 在这个特定的上下文中 我一周中有一系列天 我想使用以下命令显示从今天开始的接下来 7 天的日期名称Date getDay
  • 为什么 C++ 编译器对许多大括号的处理方式不同?

    在下面的 C 20 程序中 我错误地添加了一对额外的弯曲大括号 in B A include
  • 如何在样式组件中访问 Material-ui 的主题

    我将 CRA 与 Material ui 和 Styled Components 类型的样式一起使用 在构建 CSS 时 我想访问 Material ui 的默认主题 package json 的一部分 dependencies react
  • 两点层之间的距离矩阵

    我有两个数组 其中包含不同大小的点坐标 shapely geometry Point Eg Point X Y Point X Y Point X Y Point X Y 我想用距离函数创建这两个数组的 叉积 距离函数来自shapely g
  • RETROFIT 如何解析此响应

    我正在尝试解析这个 json 响应雅虎YQL http chartapi finance yahoo com instrument 1 0 goog chartdata type quote range 1d json使用 Retrofit
  • 如何使用 Chromium 发送帖子和标题数据?

    我正在尝试将一些代码从 TWebBrowser 转换为 Chromium 但无法弄清楚如何使用 HTTP 请求发送帖子和标头数据 下面是我正在尝试实现的 TWebBrowser 功能 var VHeader PostData OleVari
  • 如何为产品类别设置 SQL 表结构?

    我对 SQL 还很陌生 目前正在尝试用 PHP 和 MySql 制作一个简单的产品页面 现在我有一个products有我的产品的表id name price and stock 编辑 样本products tables id name pr
  • 不同命名空间中 k8s 的入口配置

    我需要在 azure k8s 上配置 Ingress Nginx 我的问题是是否可以在一个命名空间等中配置 ingress ingress nginx 和其他命名空间中的一些服务 例如 资源 我的文件看起来像这样 ingress nginx
  • 在 Heroku 上运行 pdf2htmlEX

    我正在尝试奔跑pdf2htmlEX https github com coolwanglu pdf2htmlEX在赫罗库上 起初 我想到在具有与 Heroku 相同堆栈的虚拟机上编译 pdf2htmlEX 然后将二进制文件包含在 git 存
  • 如何从 PHP 字符串中获取 64 位整数哈希值?

    我需要 64 位字符串整数哈希值来实现哈希映射之类的功能 在我看来 没有可以返回 64 位整数的原生 PHP 哈希功能 我认为可以获取 sha1 哈希值的第一部分并将其转换为整数 然而 这不会带来最好的性能 而且转换似乎很棘手 当然 如果不
  • VBA 6.0 和 VBA 7.0 有什么区别?

    我注意到 Office 2010 附带了 Visual Basic for Applications 7 0 但是我似乎找不到太多关于所做更改的文档 有没有人有更改摘要或描述差异的任何资源 VBA6 和 VBA7 之间并没有太多变化 引入
  • 使用 JSoup 时选择具有多个类的元素

    我正在解析网站上的一些表格 特别是我试图按类名提取以下单元格 Elements e d select span class bld lrg red for Element element e System out println eleme
  • 如何捕捉 contentEditable 粘贴事件?

    我有一个很棒的可编辑文本区域wysihat http github com josh wysihat 和内容可编辑 我确实需要一种方法来拦截粘贴事件以阻止它们 或者在允许插入之前处理它们的 DOM 人们可以将整个网页粘贴到可编辑区域 这有点
  • Dependency Walker 未显示所有依赖的 Dll

    我有一个 fortran dll 我想知道它所依赖的程序集再分配目的 http software intel com en us forums showthread php t 73161 我发现的一件事是依赖项步行器没有显示所有依赖项 即
  • 复制上个月的值并插入到新行中

    这是我当前表的示例 1 表名称 TotalSales Name Year Month Sales Alfred 2011 1 100 我想要做的是创建一个像这样的表 添加一个新行 上个月的销售额 2 表名称 TotalSales Name
  • PHPstorm PHPunit 代码共同覆盖

    当我在 PHPstorm 中运行测试套件时 所有代码覆盖率都为 0 我知道这不是真的 当我从命令行运行 PHPunit 时 记录的 HTML 输出文档显示我实际上确实有覆盖率并列出所有详细信息 在 PHPstorm 中 我将 PHP 解释器
  • 从 xml 节点获取行号 - java

    我已经解析了一个 XML 文件并获得了一个我感兴趣的节点 现在如何在源 XML 文件中找到该节点出现的行号 编辑 目前我正在使用 SAXParser 来解析我的 XML 不过 我会对使用任何解析器的解决方案感到满意 除了节点之外 我还有节点