JavaRush /Блоги Java /Random-TG /Асосҳои XML барои барномасози Java - Қисми 3.1 аз 3 - SAX...
Ярослав
Сатҳи
Днепр

Асосҳои XML барои барномасози Java - Қисми 3.1 аз 3 - SAX

Дар гурӯҳ нашр шудааст
Муқаддима Салом ба ҳама хонандагони мақолаи охирини ман ва ман мехоҳам шуморо табрик намоям: чизҳои мураккаб дар бораи XML пушти сари мост. Ин мақола дорои code дар Java хоҳад буд. Як каме назария ва баъд амалия мешавад. Аз сабаби он, ки як порчаи мавод дар SAX 10 саҳифаро дар Word пур кардааст, ман фаҳмидам, ки ман ба маҳдудиятҳо мувофиқат карда наметавонам. Аз ин ру, моддаи 3 ба 3 моддаи алохида таксим карда мешавад, сарфи назар аз он ки он чи кадар ачибе бошад. Ҳама чиз бо ин тартиб хоҳад буд: SAX -> DOM -> JAXB. Ин мақола танҳо ба SAX тамаркуз хоҳад кард. PS Дар курс дар ҷое вазифае вуҷуд дошт, ки дар он бояд ҳамаи унсурҳои дохorро дар файли HTML намоиш диҳед. Пас аз ин мақола, шумо метавонед ин корро бидуни хондани сатр ба сатр бо BufferedReaderалгоритмҳои коркарди анъанавӣ ва мураккаб иҷро кунед ва инчунин ҳалли шабеҳ дар мисоли охирини амалӣ дода мешавад. Биёед оғоз кунем :) SAX (Simple API for XML) - НАЗАРИЯ Коркарди SAX тавре тарҳрезӣ шудааст, ки он танҳо файлҳои XML-ро пайдарпай мехонад ва ба рӯйдодҳои гуногун вокуниш нишон медиҳад ва баъд аз он маълумотро ба коркардкунандаи рӯйдодҳои махсус медиҳад. Он дорои якчанд рӯйдодҳо мебошад, аммо бештар маъмул ва муфидтаринҳо инҳоянд:
  1. startDocument— ибтидои хуччат
  2. endDocument- охири ҳуҷҷат
  3. startElement- кушодани элемент
  4. endElement- бастани элемент
  5. characters— иттилооти матнӣ дар дохor элементҳо.
Ҳама рӯйдодҳо дар коркардкунандаи рӯйдодҳо коркард карда мешаванд , ки бояд эҷод карда шаванд ва усулҳо бекор карда шаванд . Афзалиятҳо: маҳсулнокии баланд аз ҳисоби усули «мустақим»-и хондани маълумот, хароҷоти хотираи кам. Камбудиҳо: функсияҳои маҳдуд, ки маънои онро дорад, ки дар масъалаҳои ғайрихаттӣ мо бояд онро такмил диҳем. SAX (Simple API for XML) - АМРИКО Фавран рӯйхати воридотро пешкаш кунед, то шумо чизеро ҷустуҷӯ ва иштибоҳ надиҳед:
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;
Акнун, аввал, мо бояд як SAXParser эҷод кунем:
public class SAXExample {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Creation фабрики и образца parserа
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
    }
}
Тавре ки шумо мебинед, шумо бояд аввал як корхона созед ва баъд худи parserро дар завод эҷод кунед. Акнун, ки мо худи таҳлилгар дорем, барои рӯйдодҳои он ба мо коркардкунанда лозим аст. Барои ин ба мо синфи алоҳида лозим аст, то ки бароҳатии мо бошад:
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 {
            // Тут будет логика реакции на пустое пространство внутри элементов (пробелы, переносы строчек и так далее).
        }
    }
}
Мо синферо таъсис додем, ки бо тамоми усулҳое, ки барои коркарди рӯйдодҳое, ки дар назария номбар шудаанд, лозим буд. Каме бештар назарияи иловагӣ: Каме дар бораи characters: агар элемент матн дошта бошад, масалан, " салом ", пас, аз ҷиҳати назариявӣ, методро барои ҳар як аломати алоҳида 5 маротиба дар як саф даъват кардан мумкин аст, аммо ин кори бузург нест, зеро ҳама чиз то ҳол кор хоҳад кард. Дар бораи startElementва усулҳо endElement:uri - ин фазоест, ки дар он элемент ҷойгир аст, localName- ин номи элемент бе префикс аст, qName- ин номи элемент бо префикс аст (агар вуҷуд дошта бошад, дар акси ҳол танҳо ном аз элемент). uriва localNameҳамеша холӣ аст, агар мо коркарди фазоро дар корхона фаъол накарда бошем. Ин бо усули завод ба чо оварда мешавад setNamespaceAware(true). Он гоҳ мо метавонем фосила ( uri) ва элементҳоеро, ки дар пешашон префикс доранд ( localName) гирем. Вазифаи №1 - Мо XML-и зерин дорем
<?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>
Ҳадафи мо: гирифтани ҳама маълумот дар бораи ҳамаи кормандон аз ин файл. Аввалан, мо бояд як синф эҷод кунемEmployee:
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;
    }
}
Ва дар синфи асосии мо SAXExampleба мо рӯйхат бо ҳамаи кормандон лозим аст:
private static ArrayList<Employee> employees = new ArrayList<>();
Акнун биёед бодиққат бубинем, ки маълумоте, ки ба мо лозим аст, дар файли XML куҷост. Ва, тавре ки мо мебинем, ҳама маълумоте, ки ба мо лозим аст, атрибутҳои элементҳо мебошанд employee. Ва азбаски startElementмо чунин як параметри муфид дорем attributes, пас мо вазифаи хеле содда дорем. Аввалан, биёед усулҳои нолозимро хориҷ кунем, то codeи моро вайрон накунем. Ба мо танҳо лозим аст startElement. Ва дар худи усул, мо бояд маълумотро аз атрибутҳои теги корманд ҷамъ кунем. Диққат:
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));
            }
        }
    }
}
Мантиқ оддӣ аст: агар номи элемент бошад employee, мо танҳо дар бораи атрибутҳои он маълумот мегирем. Усули муфид вуҷуд attributesдорад, ки шумо метавонед номи атрибутро дониста, арзиши онро ба даст оред. Ин аст он чизе ки мо истифода бурдем. Ҳоло, ки мо коркардкунандаи рӯйдодҳоро барои оғози элемент офаридаем, мо бояд файли XML-и худро таҳлил кунем . Барои ин, танҳо ин корро кунед:
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));
            }
        }
    }
}
Дар усули таҳлил шумо бояд роҳро ба файли xml ва коркардкунандаи эҷодкардаатон гузаронед. Ҳамин тавр, бо истифода аз ин code мо аз ин XML маълумот гирифтем:
<?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>
Ва мо натиҷаи зеринро гирифтем:
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
Миссия иҷро шуд! Вазифаи №2 - мо XML-и зерин дорем:
<?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>
Ҳадафи мо: гирифтани ҳама маълумот дар бораи ҳамаи кормандон аз ин файл. Ин мушкилот ба хубӣ нишон медиҳад, ки чӣ гуна файли XML-и суст сохташуда метавонад навиштани codeро душвортар кунад. Тавре ки шумо мебинед, маълумот дар бораи ном ва мавқеъ ҳоло ҳамчун иттилооти матнӣ дар дохor элементҳои nameва нигоҳ дошта мешавад job. Барои хондани матн дар дохor элементҳо, мо усули аломатҳоро дорем. Барои ин, мо бояд синфи нави коркардкунандаро бо мантиқи такмилёфта эҷод кунем. Фаромӯш накунед, ки коркардкунандагон синфҳои мукаммал мебошанд, ки қодиранд мантиқи ҳама гуна мураккабиро нигоҳ доранд. Аз ин рӯ, ҳоло мо протсессори худро танзим мекунем. Дарвоқеъ, қайд кардан кофӣ аст, ки мо ҳамеша навбат nameмегузорем jobва муҳим нест, ки бо кадом тартиб, мо метавонем ном ва касбро ба осонӣ ба тағирёбандаҳои алоҳида захира кунем ва вақте ки ҳарду тағирёбанда захира карда мешаванд, корманди худро эҷод кунед. Танҳо дар ин ҷо, дар баробари оғози элемент, мо барои матн дар дохor элемент параметр надорем. Мо бояд усулҳоро дар матн истифода барем. Аммо чӣ гуна мо иттилооти матниро дар дохor элемент ба даст меорем, агар ин усулҳои тамоман гуногун бошанд? Ҳалли ман: мо бояд танҳо номи элементи охиринро дар хотир дошта бошем ва charactersтафтиш кунем, ки дар кадом элемент маълумотро мехонем. Шумо инчунин бояд дар хотир доред, ки аломатҳои <codee> ҳамаи аломатҳои дохor элементҳоро мехонанд, яъне ҳамаи фосилаҳо ва ҳатто танаффусҳои сатр хонда мешаванд. Ва мо ба онҳо ниёз надорем. Мо бояд ин маълумотро сарфи назар кунем, зеро он нодуруст аст.</codee> Code:
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;
            }
        }
    }
}
Тавре ки шумо мебинед, аз сабаби мураккабии ғайриоддии сохтори файли XML, codeи мо ба таври назаррас мураккабтар шудааст. Бо вуҷуди ин, code мураккаб нест. Тавсиф: мо тағирёбандаҳоро барои нигоҳ доштани маълумот дар бораи корманд ( name, job) офаридем , инчунин як тағирёбанда lastElementNameбарои сабти кадом элементе, ки мо дар дохor он ҳастем. Пас аз ин, дар усул charactersмо маълумотро филтр мекунем ва агар дар он ҷо ҳанӯз маълумот мавҷуд бошад, ин маънои онро дорад, ки ин матнест, ки ба мо лозим аст ва сипас бо истифода аз он муайян мекунем, ки ин ном ё касб аст lastElementName. Дар усул endElement, мо тафтиш мекунем, ки оё ҳама маълумот хонда шудааст ва агар ин тавр бошад, мо корманд эҷод мекунем ва маълумотро аз нав танзим мекунем. Натиҷаи маҳлул ба мисоли аввал баробар аст:
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
Ҳамин тариқ, ин мушкилот ҳал карда шуд , аммо шумо мебинед, ки мураккабӣ баландтар аст. Аз ин рӯ, мо метавонем хулоса барорем, ки нигоҳ доштани иттилооти матнӣ дар атрибутҳо нисбат ба унсурҳои алоҳида бештар дурусттар хоҳад буд. Ва боз як вазифаи ширине, ки мушкилотро дар JavaRush дар бораи намоиш додани маълумот дар бораи элемент дар HTML қисман ҳал мекунад, танҳо онро каме таҳрир кардан лозим аст, дар ин ҷо мо танҳо ҳамаи элементҳоро дар дохor элемент номбар мекунем :) Вазифаи №3 - бо назардошти унсури элемент, номҳо ва атрибутҳои ҳамаи унсурҳои дохorро нишон диҳед; агар элемент ёфт нашавад, онро нишон диҳед. Барои ин вазифа мо файли XML-ро истифода мебарем:
<?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>
Тавре ки шумо мебинед, мо дар ин ҷо се сенарияи имконпазир дорем: root, mysql, oracle. Пас аз он, барнома тамоми маълумотро дар бораи ҳамаи унсурҳои дар дохor он нишон медиҳад. Мо инро чӣ тавр карда метавонем? Ва ин хеле содда аст: мо бояд танҳо як тағирёбандаи мантиқӣ эълон кунем isEntered, ки нишон медиҳад, ки оё ба мо элемент дар дохor он лозим аст ва агар дар дохor он бошад, ҳама маълумотро аз startElement. Рамзи ҳалли:
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;
        }
    }
}
Дар ин code ҳангоми ворид кардани элементе, ки дар бораи он ба мо маълумот лозим аст, мо парчамро isEnteredба true муқаррар мекунем, яъне мо дар дохor элемент ҳастем. Ва ҳамин ки мо дар дохor элемент ҳастем, мо танҳо ҳар як унсури навро коркард мекунем startElementва медонем, ки он маҳз як унсури дохorи элементи мост. Ҳамин тавр, мо номи элемент ва унвони онро мебарорем. Агар элемент дар файл ёфт нашуда бошад, пас мо тағирёбанда дорем isFound, ки ҳангоми пайдо шудани элемент муқаррар карда мешавад ва агар он нодуруст бошад, паёме нишон дода мешавад, ки элемент ёфт нашуд. Ва чунон ки шумо мебинед, дар мисол мо як элементро ба конструктор SearchingXMLHandlerгузаштем . rootХулоса барои ӯ:
Найден элемент <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
Ҳамин тариқ, мо ҳама маълумотро дар бораи унсурҳои дохилӣ ва атрибутҳои онҳо гирифтем. Мушкилот ҳал шудааст. <h2>Эпилог</h2>Шумо дидед, ки SAX як абзори ҷолиб ва хеле муассир аст ва он метавонад бо тарзҳои гуногун, барои мақсадҳои гуногун ва ғайра истифода шавад, ба шумо танҳо лозим аст, ки ба мушкилот аз тарафи рост нигоҳ кунед. тараф, чи тавре ки дар супориши раками 2 ва 3 нишон дода шудааст, ки дар он чо САХ усулхои бевоситаи халли масъаларо пешбинй накардааст, вале ба шарофати заковати худ мо тавонистем, ки аз вазъият баромад кунем. Қисми навбатии мақола пурра ба DOM бахшида мешавад. Умедворам, ки шиносоӣ бо SAX ба шумо маъқул шуд. Таҷриба кунед, амал кунед ва шумо хоҳед фаҳмид, ки ҳама чиз хеле оддӣ аст. Ва ин ҳама, барори кор дар барномасозии шумо ва бесаброна интизори қисмат дар бораи DOM. Муваффақият дар таҳсил :) Мақолаи қаблӣ: [Мусобиқа] Асосҳои XML барои барномасози Java - Қисми 2 аз 3 Мақолаи навбатӣ: [Мусобиқа] Асосҳои XML барои барномасози Java - Қисми 3.2 аз 3 - DOM
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION