sax 动态切换 抓取感兴趣的内容(把element当做documnet 处理)
由switch 类触发事件
import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; abstract class DelegateHandler extends DefaultHandler{ public abstract void startDocument(String uri, String localName, String qName, Attributes attributes) throws SAXException; public abstract void endDocument(String uri, String localName, String qName) throws SAXException; }
由api 触发事件
import java.util.ArrayList; import java.util.List; import java.util.Map; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; class SwitchHandler extends DefaultHandler { private final Map<String, DelegateHandler> handlerMap; private List<String> path = new ArrayList<String>(); private String currentHandlerPath = null; public SwitchHandler(Map<String, DelegateHandler> handlerMap) { this.handlerMap = handlerMap; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // update path (increase) setPath(qName, true); String path = getPath(); // startDocument if (handlerMap.containsKey(path)) { handlerMap.get(path).startDocument(uri, localName, qName, attributes); currentHandlerPath = path; } // startElement else if (currentHandlerPath != null && path.startsWith(currentHandlerPath)) { handlerMap.get(currentHandlerPath).startElement(uri, localName, qName, attributes); } } @Override public void characters(char ch[], int start, int length) throws SAXException { if (currentHandlerPath != null) { handlerMap.get(currentHandlerPath).characters(ch, start, length); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { String path = getPath(); // endDocument if (handlerMap.containsKey(path)) { handlerMap.get(path).endDocument(uri, localName, qName); currentHandlerPath = null; } // endElement else if (currentHandlerPath != null && path.startsWith(currentHandlerPath)) { handlerMap.get(currentHandlerPath).endElement(uri, localName, qName); } // update path (reduce) setPath(qName, false); } public String getPath() { StringBuilder sb = new StringBuilder(); for (String str : this.path) { sb.append("/"); sb.append(str); } return sb.toString(); } public void setPath(String qName, boolean add) { if (add) { this.path.add(qName); } else { this.path.remove(path.size() - 1); } } }
具体的实现
import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; 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; public class SaxTest { public static void main(String[] args) throws Exception { SaxTest saxTest = new SaxTest(); InputStream in = SaxTest.class.getResourceAsStream("test.xml"); InputStreamReader inr = new InputStreamReader(in); System.out.println(saxTest.exchange(inr)); } public String exchange(Reader reader) throws Exception { // xpath Map<String, DelegateHandler> handlerMap = new HashMap<String, DelegateHandler>(); TeacherHandler teacherHandler = new TeacherHandler(); StudentHandler studentHandler = new StudentHandler(); handlerMap.put("/class/teacher", teacherHandler); handlerMap.put("/class/student", studentHandler); SwitchHandler switchHandler = new SwitchHandler(handlerMap); // sax SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(switchHandler); xmlReader.parse(new InputSource(reader)); // data StringWriter writer = new StringWriter(); for (String teacher : teacherHandler.teacherList) { writer.write("teacher:" + teacher + "\n"); } for (String student : studentHandler.studentList) { writer.write("student:" + student + "\n"); } return writer.toString(); } private class TeacherHandler extends DelegateHandler { List<String> teacherList = new ArrayList<String>(); StringBuilder characters = new StringBuilder(); String id = null; String name = null; @Override public void startDocument(String uri, String localName, String qName, Attributes attributes) throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { } @Override public void characters(char[] ch, int start, int length) throws SAXException { characters.append(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equals("id")) { id = characters.toString().trim(); } else if (qName.equals("name")) { name = characters.toString().trim(); teacherList.add(id + " = " + name); } characters.setLength(0); } @Override public void endDocument(String uri, String localName, String qName) throws SAXException { } } private class StudentHandler extends DelegateHandler { List<String> studentList = new ArrayList<String>(); StringBuilder characters = new StringBuilder(); String id = null; String name = null; @Override public void startDocument(String uri, String localName, String qName, Attributes attributes) throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { } @Override public void characters(char[] ch, int start, int length) throws SAXException { characters.append(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equals("id")) { id = characters.toString().trim(); } else if (qName.equals("name")) { name = characters.toString().trim(); studentList.add(id + " = " + name); } characters.setLength(0); } @Override public void endDocument(String uri, String localName, String qName) throws SAXException { } } }
测试文件:
<class> <teacher> <id>t01</id> <name>SUN</name> </teacher> <teacher> <id>t02</id> <name>ZHANG</name> </teacher> <student> <id>s01</id> <name>Lucy</name> </student> <student> <id>s02</id> <name>Lili</name> </student> </class>
结果:
teacher:t01 = SUN teacher:t02 = ZHANG student:s01 = Lucy student:s02 = Lili
补充:
可通过构造函数传入感兴趣的字段,“a,b,c,d”
补充(如果控制顺序):
import java.util.LinkedHashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<String, String> linkedHashMap = new LinkedHashMap<String, String>(); linkedHashMap.put("a", "1"); linkedHashMap.put("b", "2"); // 这里不改变原有顺序 linkedHashMap.put("a", "3"); System.out.println(linkedHashMap); } }
{a=3, b=2}