SAX - это событийный парсер для XML, т.е. он последовательно читает и рабирает данные из входного потока (это может быть файл, сетевое соединение, или любой другой InputStream). Когда парсер находит структурный элемент (открывающий тег, закрывающий тег, и т.п.), он оповещает об этом слушателя, и передает ему в качестве параметра найденый элемент. Слушатель делает все необходимые операции для данного элемента.
Работа с SAX выглядит так:
1. Создаем свой обработчик событий, наследуя его от базового класса DefaultHandler, и переопределяем в нем нужные нам методы. Пусть нам надо занести данные из всех элементов <user> в ArrayList.
Код | public class SAXHandler extends DefaultHandler { private ArrayList<String> users; private boolean isUserTag = false;
public String[] getUsers() { return users.toArray(new String[users.size()]); }
@Override public void startDocument() throws SAXException { users = new ArrayList<String>(); }
@Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { isUserTag = "user".equals(qName); }
@Override public void characters(char[] ch, int start, int length) throws SAXException { if(isUserTag) users.add(new String(ch, start, length)); }
@Override public void endElement(String uri, String localName, String qName) throws SAXException { isUserTag = false; }
@Override public void endDocument() throws SAXException { } } |
2. Создаем фабрику парсеров и создаем парсер:
Код | SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); |
3. Парсим файл указав в качестве аргумента свой обработчик:
Код | SAXHandler handler = new SAXHandler(); parser.parse(new File("some.xml"), handler); |
4. Если надо, можно указать парсеру, проверять документ по схеме:
Код | SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(new File(""));
SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(false); factory.setSchema(schema); |
Примечание: это будет работать в JDK 1.5 и старше, в более младших версиях надо будет обновить JAXP.
Все вместе: Берем такой файл:
Код | <?xml version="1.0" encoding="UTF-8"?> <root> <user>User 1</user> <userParam>Param 1</userParam>
<user>User 2</user> <userParam>Param 2</userParam>
<user>User 3</user> <userParam>Param 3</userParam> </root> |
Парсим его:
Код | public class SAXHandler extends DefaultHandler { private ArrayList<String> users; private boolean isUserTag = false;
public String[] getUsers() { return users.toArray(new String[users.size()]); }
@Override public void startDocument() throws SAXException { users = new ArrayList<String>(); }
@Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { isUserTag = "user".equals(qName); }
@Override public void characters(char[] ch, int start, int length) throws SAXException { if(isUserTag) users.add(new String(ch, start, length)); }
@Override public void endElement(String uri, String localName, String qName) throws SAXException { isUserTag = false; }
@Override public void endDocument() throws SAXException { }
public static void main(String[] args) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser();
SAXHandler handler = new SAXHandler(); parser.parse(new File("some.xml"), handler);
for(String user : handler.getUsers()) System.out.println("user = " + user); } } |
Получаем на выходе:
Код | user = User 1 user = User 2 user = User 3 |
|