由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}