Java HTML / XML How to - Generate/get xpath from XML node with SAX Parser








Question

We would like to know how to generate/get xpath from XML node with SAX Parser.

Answer

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
// w  w w  . ja  v a  2s  . c  om
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

class FragmentContentHandler extends DefaultHandler {
  String xPath = "/";
  XMLReader xmlReader;
  FragmentContentHandler parent;
  StringBuilder characters = new StringBuilder();
  Map<String, Integer> elementNameCount = new HashMap<String, Integer>();
  public FragmentContentHandler(XMLReader xmlReader) {
    this.xmlReader = xmlReader;
  }
  private FragmentContentHandler(String xPath, XMLReader xmlReader,
      FragmentContentHandler parent) {
    this(xmlReader);
    this.xPath = xPath;
    this.parent = parent;
  }

  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes atts) throws SAXException {
    Integer count = elementNameCount.get(qName);
    if (null == count) {
      count = 1;
    } else {
      count++;
    }
    elementNameCount.put(qName, count);
    String childXPath = xPath + "/" + qName + "[" + count + "]";

    int attsLength = atts.getLength();
    for (int x = 0; x < attsLength; x++) {
      System.out.println(childXPath + "[@" + atts.getQName(x) + "='"
          + atts.getValue(x) + ']');
    }

    FragmentContentHandler child = new FragmentContentHandler(childXPath,
        xmlReader, this);
    xmlReader.setContentHandler(child);
  }

  @Override
  public void endElement(String uri, String localName, String qName)
      throws SAXException {
    String value = characters.toString().trim();
    if (value.length() > 0) {
      System.out.println(xPath + "='" + characters.toString() + "'");
    }
    xmlReader.setContentHandler(parent);
  }
  @Override
  public void characters(char[] ch, int start, int length) throws SAXException {
    characters.append(ch, start, length);
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser sp = spf.newSAXParser();
    XMLReader xr = sp.getXMLReader();

    xr.setContentHandler(new FragmentContentHandler(xr));
    xr.parse(new InputSource(new FileInputStream("input.xml")));
  }
}