简体   繁体   中英

Java Xml Element - Get node position in the file

I have XML file and I want to get position of a node.

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

I want to get 1) start and end positions; 2) start and end lines

How to do that? Thanks

Create a Reader that keeps track of position information you want:

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();
    }
}

Use that with a ContentHandler that stores the position information in some data structure associated with the elements.

    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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM