XPathがおもっていたより早かった。
SAXで処理されてるExchangeのCalendarItemを列挙するのをXPathにしようとおもって処理速度計測してみた。絶対SAXのほうが早いと思ってたけど、XPathも結構早かった。そしてDOM早い。
最初、大まかにDOMで取得して、CalendarItemのリスト作ったあと、各種値の取得にXPathを使うでもよいかも。
SAXとかちまちま使ってられんよ。SAXのcharactersで連続呼び出しとか大変だし。
SAX :1401 XPath :2001 DOM :944
package workaround; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class XPathVsSAX { static abstract class ElapsedTime { public long measure(int loop) throws Exception{ long start = System.currentTimeMillis(); for(int i = 0 ; i < loop; i++){ execute(); } long end = System.currentTimeMillis(); return end - start; } abstract void execute() throws Exception; } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { System.out.println("SAX :" + new ElapsedTime() { @Override void execute() throws Exception { parseBySAXNS(); } }.measure(1000)); System.out.println("XPath :" + new ElapsedTime() { @Override void execute() throws Exception { parseByXPathNS(); } }.measure(1000)); System.out.println("DOM :" + new ElapsedTime() { @Override void execute() throws Exception { parseByDOMNS(); } }.measure(1000)); } private static void parseByDOMNS() throws Exception { InputStream xml = ClassLoader.getSystemResourceAsStream("data/event_list.xml"); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); DocumentBuilder b = f.newDocumentBuilder(); Document d = b.parse(xml); NodeList items = d.getElementsByTagNameNS("http://schemas.microsoft.com/exchange/services/2006/types", "CalendarItem"); xml.close(); } private static void parseByXPathNS() throws Exception { InputStream xml = ClassLoader.getSystemResourceAsStream("data/event_list.xml"); XPathFactory f = XPathFactory.newInstance(); XPath path = f.newXPath(); NameSpaceContextMap nsmap = new NameSpaceContextMap(); nsmap.put(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI); nsmap.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI); nsmap.put("t", "http://schemas.microsoft.com/exchange/services/2006/types"); nsmap.put("soap", "http://schemas.xmlsoap.org/soap/envelope/"); nsmap.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); nsmap.put("xsd", "http://www.w3.org/2001/XMLSchema"); nsmap.put("m", "http://schemas.microsoft.com/exchange/services/2006/messages"); path.setNamespaceContext(nsmap); XPathExpression xpath = path.compile("//t:CalendarItem"); NodeList list = (NodeList) xpath.evaluate(new InputSource(xml), XPathConstants.NODESET); xml.close(); } private static void parseBySAXNS() throws Exception { InputStream xml = ClassLoader.getSystemResourceAsStream("data/event_list_1.xml"); SAXParserFactory f = SAXParserFactory.newInstance(); f.setNamespaceAware(true); SAXParser p = f.newSAXParser(); final ArrayList<String> elnames = new ArrayList<String>(); p.parse(xml, new DefaultHandler(){ static final String EXCHANGE_TYPES = "http://schemas.microsoft.com/exchange/services/2006/types"; static final String CALENDAR_ITEM = "CalendarItem"; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(uri.equals(EXCHANGE_TYPES) && localName.equals(CALENDAR_ITEM)){ elnames.add(qName); } } }); xml.close(); } } class NameSpaceContextMap extends HashMap<String,String> implements NamespaceContext{ @Override public String getNamespaceURI(String prefix) { if(prefix == null){ throw new NullPointerException("Null prefix"); } String ns = containsKey(prefix) ? get(prefix) : XMLConstants.NULL_NS_URI; return ns; } @Override public String getPrefix(String namespaceURI) { throw new UnsupportedOperationException(); } @Override public Iterator<String> getPrefixes(String namespaceURI) { throw new UnsupportedOperationException(); } }