JavaRush /Java Blog /Random-TK /Java programmisti üçin XML esaslary - 3-nji bölümiň 3.1-n...
Ярослав
Dereje
Днепр

Java programmisti üçin XML esaslary - 3-nji bölümiň 3.1-nji bölümi - SAX

Toparda çap edildi
Giriş Soňky makalamyň ähli okyjylaryna salam, we sizi gutlamak isleýärin: XML hakda çylşyrymly zatlar arkamyzda. Bu makalada Java-da kod bolar. Biraz teoriýa bolar, soň bolsa amal ediler. SAX-daky bir materialyň Word-da 10 sahypany doldurandygy sebäpli, çäklere laýyk bolup bilmejekdigime düşündim. Şonuň üçin 3-nji madda, näçe geň görünse-de, 3 aýratyn makala bölüner. Hemme zat şu tertipde bolar: SAX -> DOM -> JAXB. Bu makala diňe SAX-a gönükdiriler. PS Kursyň bir ýerinde HTML faýlynda ähli içerki elementleri görkezmek zerur bolan bir mesele bardy. Bu makaladan soň, muny adaty we çylşyrymly gaýtadan işlemek algoritmleri bilen hatar okamazdan başararsyňyz BufferedReaderwe soňky amaly mysalda şuňa meňzeş çözgüt berler. Başlalyň :) SAX (XML üçin ýönekeý API) - TEORI SA SAX işleýjisi XML faýllaryny yzygiderli okaýan we dürli hadysalara reaksiýa berýän görnüşde döredilýär, şondan soň maglumatlary ýörite hadysa işleýjisine geçirýär. Onda gaty az wakalar bar, ýöne iň ýygy we peýdaly aşakdakylar:
  1. startDocument- resminamanyň başy
  2. endDocument- resminamanyň soňy
  3. startElement- element açmak
  4. endElement- bir elementi ýapmak
  5. characters- elementleriň içindäki tekst maglumatlary.
Eventshli hadysalar döredilmeli we usullar ýok edilmeli hadysalary dolandyryjyda işlenýär . Üstünlikleri: maglumatlary okamagyň “göni” usuly sebäpli ýokary öndürijilik, ýadyň pesligi. Adetmezçilikleri: çäkli işlemegi, çyzykly däl meselelerde ony hasam arassalamaly bolarys. SAX (XML üçin ýönekeý API) - TERJIME EDIP BOLMASY andYZ we hiç zady bulaşdyrmazlyk üçin derrew importyň sanawy:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
Indi ilki bilen SAXParser döretmeli:
public class SAXExample {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Creation фабрики и образца parserа
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
    }
}
Görşüňiz ýaly, ilki bilen zawod döretmeli, soňra bolsa zawodda derňewçini döretmeli. Indi derňewçiniň özi bolansoň, wakalary üçin işleýji gerek. Munuň üçin öz amatlylygymyz üçin aýratyn synp gerek:
public class SAXExample {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
    }

    private static class XMLHandler extends DefaultHandler {
        @Override
        public void startDocument() throws SAXException {
            // Тут будет логика реакции на начало documentа
        }

        @Override
        public void endDocument() throws SAXException {
            // Тут будет логика реакции на конец documentа
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            // Тут будет логика реакции на начало element
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            // Тут будет логика реакции на конец element
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            // Тут будет логика реакции на текст между elementми
        }

        @Override
        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
            // Тут будет логика реакции на пустое пространство внутри элементов (пробелы, переносы строчек и так далее).
        }
    }
}
Nazaryýetde görkezilen wakalary dolandyrmak üçin zerur bolan ähli usullar bilen synp döretdik. Biraz goşmaça teoriýa: Birazajyk : characterseger elementde tekst, mysal üçin “ salam ” bar bolsa, teoretiki taýdan bu usuly her bir şahsyýet üçin yzly-yzyna 5 gezek çagyryp bolar, ýöne bu uly mesele däl, sebäbi hemme zat henizem işlär. Usullar we usullar barada :startElementendElementuri - bu elementiň ýerleşýän ýeri, localName- bu elementiň prefiksi bolmazdan ady, qName- bu prefiksi bolan elementiň ady (eger bar bolsa, diňe ady elementi). zawodda boş işlemäge mümkinçilik bermedik bolsak elmydama boş uri. localNameBu zawod usuly bilen amala aşyrylýar setNamespaceAware(true). uriSoň bolsa ( ) we öňündäki () prefiksi bolan elementleri alyp bileris localName. 1-nji wezipe - Aşakdaky XML bar
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<company>
    <name>IT-Heaven</name>
    <offices>
        <office floor="1" room="1">
            <employees>
                <employee name="Maksim" job="Middle Software Developer" />
                <employee name="Ivan" job="Junior Software Developer" />
                <employee name="Franklin" job="Junior Software Developer" />
            </employees>
        </office>
        <office floor="1" room="2">
            <employees>
                <employee name="Herald" job="Middle Software Developer" />
                <employee name="Adam" job="Middle Software Developer" />
                <employee name="Leroy" job="Junior Software Developer" />
            </employees>
        </office>
    </offices>
</company>
Maksadymyz: ähli işgärler hakda ähli maglumatlary şu faýldan almak. Ilki bilen synp döretmeliEmployee:
public class Employee {
    private String name, job;

    public Employee(String name, String job) {
        this.name = name;
        this.job = job;
    }

    public String getName() {
        return name;
    }

    public String getJob() {
        return job;
    }
}
Esasy synpymyzda SAXExampleähli işgärler bilen sanaw gerek:
private static ArrayList<Employee> employees = new ArrayList<>();
Indi, XML faýlynda zerur maglumatlaryň nirededigine üns bilen seredeliň. Görşümiz ýaly, bize zerur maglumatlaryň hemmesi elementleriň häsiýetleri employee. startElementMunuň ýaly peýdaly parametrimiz bolansoň , attributesdiýseň ýönekeý bir işimiz bar. Ilki bilen kodumyzy bulaşdyrmazlyk üçin gereksiz usullary aýyralyň. Bize diňe zerur startElement. Usulyň özünde bolsa, işgäriň belliginiň häsiýetlerinden maglumat ýygnamalydyrys. Üns beriň:
public class SAXExample {
    private static ArrayList<Employee> employees = new ArrayList<>();

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
    }

    private static class XMLHandler extends DefaultHandler {
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (qName.equals("employee")) {
                String name = attributes.getValue("name");
                String job = attributes.getValue("job");
                employees.add(new Employee(name, job));
            }
        }
    }
}
Logika ýönekeý: bir elementiň ady bolsa employee, diňe onuň häsiýetleri barada maglumat alarys. attributesBir atributyň adyny bilip, onuň bahasyny alyp boljak peýdaly usul bar . Ine, biz ulanýardyk. Bir elementiň başlangyjy üçin hadysa işleýjisini döredenimizden soň, XML faýlymyzy derňemeli . Munuň üçin diňe şuny ediň:
public class SAXExample {
    private static ArrayList<Employee> employees = new ArrayList<>();

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();

        XMLHandler handler = new XMLHandler();
        parser.parse(new File("resource/xml_file1.xml"), handler);

        for (Employee employee : employees)
            System.out.println(String.format("Name сотрудника: %s, его должность: %s", employee.getName(), employee.getJob()));
    }

    private static class XMLHandler extends DefaultHandler {
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (qName.equals("employee")) {
                String name = attributes.getValue("name");
                String job = attributes.getValue("job");
                employees.add(new Employee(name, job));
            }
        }
    }
}
Derňew usulynda xml faýlyna we döreden işleýjiňize ýol geçmeli. Şeýlelik bilen, bu kody ulanyp, bu XML-den maglumat çykardyk:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<company>
    <name>IT-Heaven</name>
    <offices>
        <office floor="1" room="1">
            <employees>
                <employee name="Maksim" job="Middle Software Developer" />
                <employee name="Ivan" job="Junior Software Developer" />
                <employee name="Franklin" job="Junior Software Developer" />
            </employees>
        </office>
        <office floor="1" room="2">
            <employees>
                <employee name="Herald" job="Middle Software Developer" />
                <employee name="Adam" job="Middle Software Developer" />
                <employee name="Leroy" job="Junior Software Developer" />
            </employees>
        </office>
    </offices>
</company>
Aşakdaky netijäni aldyk:
Name сотрудника: Maksim, его должность: Middle Software Developer
Name сотрудника: Ivan, его должность: Junior Software Developer
Name сотрудника: Franklin, его должность: Junior Software Developer
Name сотрудника: Herald, его должность: Middle Software Developer
Name сотрудника: Adam, его должность: Middle Software Developer
Name сотрудника: Leroy, его должность: Junior Software Developer
Iş ýerine ýetirildi! 2-nji wezipe - aşakdaky XML bar:
<?xml version="1.0" encoding="UTF-8"?>
<company>
    <name>IT-Heaven</name>
    <offices>
        <office floor="1" room="1">
            <employees>
                <employee>
                    <name>Maksim</name>
                    <job>Middle Software Developer</job>
                </employee>
                <employee>
                    <name>Ivan</name>
                    <job>Junior Software Developer</job>
                </employee>
                <employee>
                    <name>Franklin</name>
                    <job>Junior Software Developer</job>
                </employee>
            </employees>
        </office>
        <office floor="1" room="2">
            <employees>
                <employee>
                    <name>Herald</name>
                    <job>Middle Software Developer</job>
                </employee>
                <employee>
                    <name>Adam</name>
                    <job>Middle Software Developer</job>
                </employee>
                <employee>
                    <name>Leroy</name>
                    <job>Junior Software Developer</job>
                </employee>
            </employees>
        </office>
    </offices>
</company>
Maksadymyz: ähli işgärler hakda ähli maglumatlary şu faýldan almak. Bu mesele, gurluşsyz XML faýlynyň ýazuw koduny nädip kynlaşdyryp biljekdigini gowy görkezer. Görşüňiz ýaly, at we pozisiýa baradaky maglumatlar indi elementleriň içinde tekst maglumatlary hökmünde namesaklanýar job. Elementleriň içindäki teksti okamak üçin simwollar usuly bar. Munuň üçin kämilleşdirilen logika bilen täze işleýän synp döretmeli. Işleýänleriň islendik çylşyrymlylygyň logikasyny saklamaga ukyply doly synpdygyny ýatdan çykarmaň. Şonuň üçin indi prosessorymyzy sazlarys. nameAslynda, hemişe nobatçylyk edýändigimizi bellemek ýeterlikdir jobwe haýsy tertipde tapawudy ýok, ady we hünäri aýratyn üýtgeýänlere aňsatlyk bilen ýazdyryp bileris we iki üýtgeýji ýatda saklananda işgärimizi dörederis. Diňe şu ýerde, elementiň başlangyjy bilen birlikde, elementiň içindäki tekst üçin parametr ýok. Tekstde usullary ulanmalydyrys. Theseöne bular düýbünden başga usullar bolsa, bir elementiň içinde tekst maglumatyny nädip almaly? Çözüwim: diňe soňky elementiň adyny ýatda saklamaly we charactershaýsy elementi okaýandygymyzy barlamaly. Şeýle hem, <kod> nyşanlarynyň elementleriň içindäki ähli nyşanlary okaýandygyny ýadyňyzdan çykarmaly dälsiňiz, bu bolsa ähli boşluklaryň we hatda setir arakesmeleriniň hem okaljakdygyny aňladýar. Bize gerek däl. Nädogry bolany üçin bu maglumatlary äsgermezlik etmeli. </codee> Kod:
public class SAXExample {
    private static ArrayList<Employee> employees = new ArrayList<>();

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();

        AdvancedXMLHandler handler = new AdvancedXMLHandler();
        parser.parse(new File("resource/xml_file2.xml"), handler);

        for (Employee employee : employees)
            System.out.println(String.format("Name сотрудника: %s, его должность: %s", employee.getName(), employee.getJob()));
    }

    private static class AdvancedXMLHandler extends DefaultHandler {
        private String name, job, lastElementName;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            lastElementName = qName;
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            String information = new String(ch, start, length);

            information = information.replace("\n", "").trim();

            if (!information.isEmpty()) {
                if (lastElementName.equals("name"))
                    name = information;
                if (lastElementName.equals("job"))
                    job = information;
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ( (name != null && !name.isEmpty()) && (job != null && !job.isEmpty()) ) {
                employees.add(new Employee(name, job));
                name = null;
                job = null;
            }
        }
    }
}
Görşüňiz ýaly, XML faýl gurluşynyň gadaganlygy sebäpli kodumyz has çylşyrymlaşdy. Şeýle-de bolsa, kod çylşyrymly däl. Düşündiriş: Işgär ( name, job) hakda maglumatlary saklamak üçin üýtgeýjileri, şeýle hem lastElementNameiçimizdäki haýsy elementiň bardygyny ýazmak üçin üýtgeýjini döretdik. Ondan soň, charactersmaglumatlary süzýäris, eger-de ol ýerde henizem maglumat bar bolsa, bu biziň zerur tekstimizi aňladýar, soň bolsa adynyň ýa-da ulanylýan hünäriň bardygyny kesgitleýäris lastElementName. Usulda endElement, ähli maglumatlaryň okalandygyny ýa-da ýokdugyny barlaýarys, eger şeýle bolsa, işgär döredýäris we maglumatlary täzeden düzýäris. Çözüwiň çykyşy birinji mysala deňdir:
Name сотрудника: Maksim, его должность: Middle Software Developer
Name сотрудника: Ivan, его должность: Junior Software Developer
Name сотрудника: Franklin, его должность: Junior Software Developer
Name сотрудника: Herald, его должность: Middle Software Developer
Name сотрудника: Adam, его должность: Middle Software Developer
Name сотрудника: Leroy, его должность: Junior Software Developer
Şeýlelikde, bu mesele çözüldi , ýöne çylşyrymlylygyň has ýokarydygyny görüp bilersiňiz. Şonuň üçin tekst maglumatlaryny atributlarda saklamak köplenç aýratyn elementlere garanyňda has dogry bolar diýen netijä gelip bileris. JavaRush-da HTML-de bir element hakda maglumatlary görkezmek baradaky meseläni bölekleýin çözjek ýene bir süýji mesele, diňe azajyk redaktirlemeli bolar, bu ýerde diňe bir elementiň içindäki ähli elementleri sanap geçeris :) Task No. 3 - element elementini göz öňünde tutup, ähli içerki elementleriň atlaryny we atributlaryny görkeziň; element tapylmasa muny görkeziň. Bu mesele üçin aşakdaky XML faýly ulanarys:
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <oracle>
        <connection value="jdbc:oracle:thin:@10.220.140.48:1521:test1" />
        <user value="secretOracleUsername" />
        <password value="111" />
    </oracle>

    <mysql>
        <connection value="jdbc:mysql:thin:@10.220.140.48:1521:test1" />
        <user value="secretMySQLUsername" />
        <password value="222" />
    </mysql>
</root>
Görşüňiz ýaly, bu ýerde üç mümkin senari bar : root,, mysql. oracleSoňra programma içindäki ähli elementler baradaky ähli maglumatlary görkezer. Muny nädip edip bileris? Bu gaty ýönekeý: diňe isEnterediçerki elementiň gerekdigini ýa-da içerde bolsa, ähli maglumatlary okajak logiki üýtgeýjini yglan etmeli startElement. Çözgüt kody:
public class SAXExample {
    private static boolean isFound;

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();

        SearchingXMLHandler handler = new SearchingXMLHandler("root");
        parser.parse(new File("resource/xml_file3.xml"), handler);

        if (!isFound)
            System.out.println("Элемент не был найден.");
    }

    private static class SearchingXMLHandler extends DefaultHandler {
        private String element;
        private boolean isEntered;

        public SearchingXMLHandler(String element) {
            this.element = element;
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (isEntered) {
                System.out.println(String.format("Найден элемент <%s>, его атрибуты:", qName));

                int length = attributes.getLength();
                for(int i = 0; i < length; i++)
                    System.out.println(String.format("Name атрибута: %s, его meaning: %s", attributes.getQName(i), attributes.getValue(i)));
            }

            if (qName.equals(element)) {
                isEntered = true;
                isFound = true;
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (qName.equals(element))
                isEntered = false;
        }
    }
}
Bu kodda, maglumat gerek elementi girizenimizde, baýdagy isEntereddogry goýýarys, bu elementiň içindedigimizi aňladýar. Elementiň içinde bolanymyzdan soň, startElementelementimiziň içki elementidigini bilip, her täze elementi gaýtadan işleýäris. Şeýlelik bilen elementiň adyny we adyny çykarýarys. Eger element faýlda tapylmadyk bolsa, onda isFoundelement tapylanda kesgitlenýän üýtgeýjimiz bar we ýalňyş bolsa, elementiň tapylmandygy barada habar görkeziler. Görşüňiz ýaly, mysalda bir elementi konstruktora SearchingXMLHandlergeçirdik . rootNetije:
Найден элемент <oracle>, его атрибуты:
Найден элемент <connection>, его атрибуты:
Name атрибута: value, его meaning: jdbc:oracle:thin:@10.220.140.48:1521:test1
Найден элемент <user>, его атрибуты:
Name атрибута: value, его meaning: secretOracleUsername
Найден элемент <password>, его атрибуты:
Name атрибута: value, его meaning: 111
Найден элемент <mysql>, его атрибуты:
Найден элемент <connection>, его атрибуты:
Name атрибута: value, его meaning: jdbc:mysql:thin:@10.220.140.48:1521:test1
Найден элемент <user>, его атрибуты:
Name атрибута: value, его meaning: secretMySQLUsername
Найден элемент <password>, его атрибуты:
Name атрибута: value, его meaning: 222
Şeýlelik bilen, içerki elementler we olaryň häsiýetleri barada ähli maglumatlary aldyk. Mesele çözüldi. <h2> Epilogue </h2> SAX-yň gaty gyzykly guraldygyny we gaty täsirli bolandygyny, ony dürli usullar, dürli maksatlar we ş.m. ulanyp boljakdygyny gördüňiz, meselä sag tarapdan seretmeli; tarapy, 2-nji we 3-nji meselelerde görkezilişi ýaly, SAX meseläni çözmek üçin gönüden-göni usullar bilen üpjün etmedi, ýöne ussatlygymyz sebäpli ýagdaýdan çykalga tapmagy başardyk. Makalanyň indiki bölümi tutuşlygyna DOM-a bagyşlanar. SAX bilen tanyşmakdan lezzet alarsyňyz diýip umyt edýärin. Synag, tejribe ediň we hemme zadyň gaty ýönekeýdigine düşünersiňiz. Bularyň hemmesi, programmaňyz bilen üstünlik we ýakyn wagtda DOM hakda bölüme sabyrsyzlyk bilen garaşyň. Okuwyňyzda üstünlik arzuw ediň :) Öňki makala: [Bäsdeşlik] Java programmisti üçin XML esaslary - 3-nji bölümiň 2-nji bölümi Indiki makala: [Bäsdeşlik] Java programmisti üçin XML esaslary - 3-nji bölümiň 3.2-nji bölümi - DOM
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION