Во многих задачах необходимо использовать разные типы XML-файлов для разных целей.Я не буду пытаться понять необъятность и рассказать из собственного опыта, зачем мне все это нужно.
Java, пожалуй, мой любимый язык программирования.Кроме того, эта любовь усиливается тем, что вы можете решить любую проблему и придумывать велосипед не нужно.
Итак, мне потребовалось создать группу клиент-сервер с базой данных, которая позволяла бы клиенту удаленно делать записи на сервере базы данных.Нет необходимости проверять входные данные и т. Д. И т. П., Но речь не об этом.
В качестве принципа работы я без колебаний выбрал передачу информации в виде xml файла.Из следующих типов:
<? xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<doc>
<id> 3 </ id>
<fam> Ivanov </ fam>
<name> Ivan </ name>
<otc> I. </ otc>
<dateb> 10-03-2005 </ dateb>
<datep> 10-03-2005 </ datep>
<datev> 10-03-2005 </ datev>
<datebegin> 09-06-2009 </ datebegin>
<dateend> 10-03-2005 </ dateend>
<vdolid> 1 </ vdolid>
<specid> 1 </ specid>
<klavid> 1 </ klavid>
<stav> 2.0 </ stav>
<progid> 1 </ progid>
</ doc>
Упростить чтение дальше, кроме как сказать, что это информация о врачебных учреждениях.Фамилия, имя, уникальный идентификатор и т. Д.В общем, ряд данных.Этот файл благополучно попал на серверную часть, а затем приступил к разбору файла.
Из двух вариантов разбора (SAX vs DOM) я выбрал SAX view из-за того, что он работает ярче, и он первым попал мне в руки :)
Итак.Как вы знаете, для успешной работы с парсером нам нужно переопределить необходимые методы DefaultHandler.Для начала подключите необходимые пакеты.
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax. *;
Теперь мы можем начать писать наш синтаксический анализатор
public class SAXPars extends DefaultHandler {
...
}
Давайте начнем с метода startDocument ().Он, как следует из названия, реагирует на начало события документа.Здесь вы можете повесить различные действия, такие как выделение памяти, или сбросить значения, но наш пример довольно прост, поэтому просто отметьте начало работы соответствующего сообщения:
Override
public void startDocument () throws SAXException {
System.out.println ("Start parse XML ...");
}
Далее,Парсер проходит по документу, соответствует элементу его структуры.Запускает метод startElement ().А на самом деле его внешний вид такой: startElement (String namespaceURI, String localName, String qName, Attributes atts).Здесь namespaceURI - пространство имен, localName - локальное имя элемента, qName - комбинация локального имени с пространством имен (разделенных двоеточием) и atts - атрибутами этого элемента.В этом случае все просто.Достаточно использовать qName'ом и бросить его в какую-нибудь служебную строку thisElement.Таким образом мы отмечаем, в каком элементе в данный момент мы находимся.
@Override
public void startElement (String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
thisElement = qName;
}
Далее, пункт встречи, мы получаем его значение.Сюда включают методы characters ().Он имеет вид: символы (char [] ch, int start, int length).Ну тут все понятно.ch - файл, содержащий саму важность строки в этом элементе.start and length - номер услуги, указывающий начальную точку в строке и длину.
@Override
public void characters (char [] ch, int start, int length) throws SAXException {
if (thisElement.equals ("id")) {
doc.setId (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("fam")) {
doc.setFam (new String (ch, start, length));
}
if (thisElement.equals ("name")) {
doc.setName (new String (ch, start, length));
}
if (thisElement.equals ("otc")) {
doc.setOtc (new String (ch, start, length));
}
if (thisElement.equals ("dateb")) {
doc.setDateb (new String (ch, start, length));
}
if (thisElement.equals ("datep")) {
doc.setDatep (new String (ch, start, length));
}
if (thisElement.equals ("datev")) {
doc.setDatev (new String (ch, start, length));
}
if (thisElement.equals ("datebegin")) {
doc.setDatebegin (new String (ch, start, length));
}
if (thisElement.equals ("dateend")) {
doc.setDateend (new String (ch, start, length));
}
if (thisElement.equals ("vdolid")) {
doc.setVdolid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("specid")) {
doc.setSpecid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("klavid")) {
doc.setKlavid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("stav")) {
doc.setStav (new Float (new String (ch, start, length)));
}
if (thisElement.equals ("progid")) {
doc.setProgid (new Integer (new String (ch, start, length)));
}
}
Ах да.Я почти забыл.Как объект, который будет складывать напарсенные данные, говорит о типе врачей.Этот класс определен и имеет все необходимые сеттеры-геттеры.
Следующий очевидный элемент заканчивается, и за ним следует следующий.Ответственный за завершение endElement ().Он сигнализирует нам, что предмет закончился, и вы можете сделать что-нибудь в это время.Будет продолжаться.Очисти Элемент.
@Override
public void endElement (String namespaceURI, String localName, String qName) throws SAXException {
thisElement = "";
}
Получив весь документ, мы подходим к концу файла.Работа endDocument ().В нем мы можем освободить память, сделать некоторую диагностическую печать и т. Д. В нашем случае просто напишите о том, чем заканчивается разбор.
@Override
public void endDocument () {
System.out.println ("Stop parse XML ...");
}
Итак, мы получили класс для разбора нашего формата xml.Вот полный текст:
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax. *;
public class SAXPars extends DefaultHandler {
Doctors doc = new Doctors ();
String thisElement = "";
public Doctors getResult () {
return doc;
}
@Override
public void startDocument () throws SAXException {
System.out.println ("Start parse XML ...");
}
@Override
public void startElement (String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
thisElement = qName;
}
@Override
public void endElement (String namespaceURI, String localName, String qName) throws SAXException {
thisElement = "";
}
@Override
public void characters (char [] ch, int start, int length) throws SAXException {
if (thisElement.equals ("id")) {
doc.setId (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("fam")) {
doc.setFam (new String (ch, start, length));
}
if (thisElement.equals ("name")) {
doc.setName (new String (ch, start, length));
}
if (thisElement.equals ("otc")) {
doc.setOtc (new String (ch, start, length));
}
if (thisElement.equals ("dateb")) {
doc.setDateb (new String (ch, start, length));
}
if (thisElement.equals ("datep")) {
doc.setDatep (new String (ch, start, length));
}
if (thisElement.equals ("datev")) {
doc.setDatev (new String (ch, start, length));
}
if (thisElement.equals ("datebegin")) {
doc.setDatebegin (new String (ch, start, length));
}
if (thisElement.equals ("dateend")) {
doc.setDateend (new String (ch, start, length));
}
if (thisElement.equals ("vdolid")) {
doc.setVdolid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("specid")) {
doc.setSpecid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("klavid")) {
doc.setKlavid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("stav")) {
doc.setStav (new Float (new String (ch, start, length)));
}
if (thisElement.equals ("progid")) {
doc.setProgid (new Integer (new String (ch, start, length)));
}
}
@Override
public void endDocument () {
System.out.println ("Stop parse XML ...");
}
}
Я надеюсь, что тема помогла легко представить суть парсера SAX.
Не судите строго по первой статье :) Надеюсь, это было хоть кому-то полезно.
UPD: для запуска этого парсера вы можете использовать этот код:
SAXParserFactory factory = SAXParserFactory.newInstance ();
SAXParser parser = factory.newSAXParser ();
SAXPars saxp = new SAXPars ();
parser.parse (new File ("..."), saxp);