This class uses SAX to parse an XML file and creates XPath expressions for each element encountered. As is mentioned in the code, the algorithm is not correct in all circumstances. The problem was discussed
in this Saloon thread.
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
public class SAXCreateXPath extends DefaultHandler {
private Map<String, Integer> tagCount;
private Stack<String> tags;
String lastClosedTag;
private String getCurrentXPath() {
String str = "//";
boolean first = true;
for (String tag : tags) {
if (first)
str = str + tag;
else
str = str + "/" + tag;
str += "["+tagCount.get(tag)+"]";
first = false;
}
return str;
}
@Override
public void startDocument() throws SAXException {
tags = new Stack();
tagCount = new HashMap<String, Integer>();
}
@Override
public void startElement (String namespaceURI, String localName, String qName, Attributes atts)
throws SAXException
{
boolean isRepeatElement = false;
if (tagCount.get(localName) == null) {
tagCount.put(localName, 0);
} else {
tagCount.put(localName, 1 + tagCount.get(localName));
}
if (lastClosedTag != null) {
if (lastClosedTag.equals(localName)) {
isRepeatElement = true;
} else {
tags.pop();
}
}
if (! isRepeatElement) {
tags.push(localName);
}
System.out.println(getCurrentXPath());
lastClosedTag = null;
}
@Override
public void endElement (String uri, String localName, String qName) throws SAXException {
if (lastClosedTag != null) {
tags.pop();
}
lastClosedTag = localName;
}
public static void main (String[] args) throws Exception {
if (args.length < 1) {
System.err.println("Usage: SAXCreateXPath <file.xml>");
System.exit(1);
}
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(false);
SAXParser saxParser = spf.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(new SAXCreateXPath());
String filename = args[0];
String path = new File(filename).getAbsolutePath();
if (File.separatorChar != '/') {
path = path.replace(File.separatorChar, '/');
}
if (!path.startsWith("/")) {
path = "/" + path;
}
xmlReader.parse("file:"+path);
}
}
CategoryCodeSamples