Java Xml元素 - 获取文件中的节点位置

时间:2015-10-19 14:32:48

标签: java xml

我有XML文件,我想获得一个节点的位置。

<Root>
    <Node1></Node1>
</Root>

我想得到1)开始和结束位置; 2)开始和结束行

怎么做?感谢

1 个答案:

答案 0 :(得分:0)

创建一个能够跟踪所需位置信息的阅读器:

static public class MyReader extends Reader {

    final private Reader internalReader;
    private int pos;
    private int line;

    public MyReader(Reader internalReader) {
        this.internalReader = internalReader;
    }

    public int getPos() {
        return pos;
    }

    public int getLine() {
        return line;
    }


    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {

        int chars_read = internalReader.read(cbuf, off, 1);
        pos += chars_read;
        if(cbuf[off] =='\n' && chars_read > 0) {
            line++;
        }
        return chars_read;
    }

    @Override
    public void close() throws IOException {
        internalReader.close();
    }
}

将其与ContentHandler一起使用,ContentHandler将位置信息存储在与元素关联的某些数据结构中。

    String xmlString = "<Root>\n"
            + "    <Node1></Node1>\n"
            + "</Root>";
    StringReader strReader = new StringReader(xmlString);
    MyReader reader = new MyReader(strReader);
    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    XMLReader xmlreader = parser.getXMLReader();
    Map<String,List<Integer>> startMap = new HashMap<>();
    Map<String,List<Integer>> endMap = new HashMap<>();
    Map<String,List<Integer>> startLineMap = new HashMap<>();
    Map<String,List<Integer>> endLineMap = new HashMap<>();

    DefaultHandler handler = new DefaultHandler() {

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName); //To change body of generated methods, choose Tools | Templates.
            List<Integer> l = endMap.get(qName);
            if(null == l) {
                l = new ArrayList<>();
            }
            l.add(reader.getPos());
            endMap.put(qName, l);
            List<Integer> ll = endLineMap.get(qName);
            if(null == ll) {
                ll= new ArrayList<>();
            }
            ll.add(reader.getLine());
            endLineMap.put(qName, ll);
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes); //To change body of generated methods, choose Tools | Templates.
            List<Integer> l = startMap.get(qName);
            if(null == l) {
                l = new ArrayList<>();
            }
            l.add(reader.getPos());
            startMap.put(qName, l);
            List<Integer> ll = startLineMap.get(qName);
            if(null == ll) {
                ll= new ArrayList<>();
            }
            ll.add(reader.getLine());
            startLineMap.put(qName, ll);
        }
    };
    xmlreader.setContentHandler(handler);
    xmlreader.parse(new InputSource(reader));
    System.out.println("startMap = " + startMap);
    System.out.println("endMap = " + endMap);
    System.out.println("startLineMap = " + startLineMap);
    System.out.println("endLineMap = " + endLineMap);