JavaRush /Blog Jawa /Random-JV /Dasar XML kanggo Programmer Java - Part 3.1 saka 3 - SAX
Ярослав
tingkat
Днепр

Dasar XML kanggo Programmer Java - Part 3.1 saka 3 - SAX

Diterbitake ing grup
Pambuka Halo kanggo kabeh sing maca artikelku sing durung pungkasan, lan aku pengin ngucapake selamat: barang rumit babagan XML ana ing mburi kita. Artikel iki bakal ngemot kode ing Jawa. Bakal ana teori sethithik, banjur praktik. Amarga kasunyatan sing siji Piece saka materi ing SAX kapenuhan 10 kaca ing Word, Aku temen maujud sing aku ora bisa pas menyang watesan. Mula, artikel 3 bakal dipérang dadi 3 artikel sing kapisah, ora preduli sepira aneh. Kabeh bakal ana ing urutan iki: SAX -> DOM -> JAXB. Artikel iki mung bakal fokus ing SAX. PS Ana tugas nang endi wae ing Course ngendi iku perlu kanggo nampilake kabeh unsur internal ing file HTML. Sawise artikel iki, sampeyan bakal bisa nindakake iki tanpa maca baris dening baris karo BufferedReaderalgoritma pangolahan conventional lan Komplek, lan uga solusi sing padha bakal diwenehi ing conto praktis pungkasan. Ayo dadi miwiti :) SAX (API prasaja kanggo XML) - TEORI Handler SAX dirancang kanthi cara sing mung maca file XML kanthi urutan lan nanggepi acara sing beda-beda, sawise iku ngirim informasi kasebut menyang pawang acara khusus. Wis sawetara acara, nanging sing paling kerep lan migunani yaiku ing ngisor iki:
  1. startDocument- wiwitan dokumen
  2. endDocument- mburi dokumen
  3. startElement- mbukak unsur
  4. endElement- nutup unsur
  5. characters- informasi teks nang unsur.
Kabeh acara diproses ing panangan acara , sing kudu digawe lan cara diganti . Kaluwihan: kinerja dhuwur amarga cara "langsung" maca data, biaya memori kurang. Cacat: fungsi winates, tegese ing masalah non-linear kita kudu nyaring. SAX (Simple API for XML) – PRAKTIKA Langsung dhaptar impor supaya sampeyan ora nggolèki lan bingung apa-apa:
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;
Saiki, pisanan, kita kudu nggawe SAXParser:
public class SAXExample {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Creation фабрики и образца parserа
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
    }
}
Nalika sampeyan bisa ndeleng, pisanan sampeyan kudu nggawe pabrik, lan banjur nggawe parser dhewe ing pabrik. Saiki kita duwe parser dhewe, kita butuh panangan kanggo acara kasebut. Kanggo iki, kita butuh kelas sing kapisah kanggo kepenak kita dhewe:
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 {
            // Тут будет логика реакции на пустое пространство внутри элементов (пробелы, переносы строчек и так далее).
        }
    }
}
Kita nggawe kelas kanthi kabeh cara sing dibutuhake kanggo nangani acara sing didhaptar ing teori kasebut. A teori tambahan sethitik liyane: A sethitik babagan characters: yen unsur ngemot teks, contone, " hello ", banjur, miturut teori, cara bisa disebut 5 kaping saurutan kanggo saben karakter individu, nanging iki ora masalah gedhe, awit kabeh isih bakal bisa. Babagan startElementlan metode endElement:uri - iki spasi ing ngendi unsur dumunung, localName- iki jeneng unsur tanpa ater-ater, qName- iki jeneng unsur karo ater-ater (yen ana siji, liya mung jeneng. saka unsur). urilan localNametansah kosong yen kita durung ngaktifake pangolahan spasi ing pabrik. Iki ditindakake kanthi cara pabrik setNamespaceAware(true). Banjur kita bisa entuk spasi ( uri) lan unsur kanthi awalan ing ngarepe ( localName). Tugas #1 - Kita duwe XML ing ngisor iki
<?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>
Tujuan kita: entuk kabeh informasi babagan kabeh karyawan saka file iki. Pisanan, kita kudu nggawe kelasEmployee:
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;
    }
}
Lan ing kelas utama SAXExamplekita butuh dhaptar karo kabeh karyawan:
private static ArrayList<Employee> employees = new ArrayList<>();
Saiki ayo goleki kanthi teliti ing ngendi informasi sing dibutuhake ing file XML. Lan, kaya sing bisa dideleng, kabeh informasi sing dibutuhake yaiku atribut unsur kasebut employee. Lan amarga startElementkita duwe parameter migunani kaya attributes, mula kita duwe tugas sing cukup prasaja. Pisanan, ayo mbusak cara sing ora perlu supaya ora ngganggu kode kita. Kita mung butuh startElement. Lan ing cara kasebut, kita kudu ngumpulake informasi saka atribut tag karyawan. manungsa waé:
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 punika prasaja: yen jeneng unsur punika employee, kita mung bakal nampa informasi bab sawijining atribut. Ana attributescara sing migunani ing ngendi, ngerti jeneng atribut, sampeyan bisa entuk regane. Sing kita digunakake. Saiki kita wis nggawe pengendali acara kanggo wiwitan unsur, kita kudu ngurai file XML kita . Kanggo nindakake iki, mung nindakake iki:
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));
            }
        }
    }
}
Ing cara parse sampeyan kudu ngliwati path menyang file xml lan pawang sing digawe. Dadi, nggunakake kode iki, kita njupuk informasi saka XML iki:
<?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>
Lan kita entuk output ing ngisor iki:
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
Misi wis rampung! Tugas #2 - kita duwe XML ing ngisor iki:
<?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>
Tujuan kita: entuk kabeh informasi babagan kabeh karyawan saka file iki. Masalah iki bakal nduduhake carane file XML sing ora kabentuk bisa nggawe kode nulis luwih angel. Kaya sing sampeyan ngerteni, informasi babagan jeneng lan posisi saiki disimpen minangka informasi teks ing namelan unsur job. Kanggo maca teks ing unsur, kita duwe metode karakter. Kanggo nindakake iki, kita kudu nggawe kelas handler anyar kanthi logika sing luwih apik. Aja lali manawa pawang minangka kelas lengkap sing bisa nyimpen logika saka kerumitan apa wae. Mulane, saiki kita bakal nyetel prosesor kita. Ing kasunyatan, iku cukup kanggo Wigati sing kita tansah namenjupuk jobgiliran, lan ora Matter ing urutan apa, kita bisa gampang nyimpen jeneng lan Profesi menyang variabel kapisah, lan nalika loro variabel disimpen, nggawe karyawan kita. Mung ing kene, bebarengan karo wiwitan unsur, kita ora duwe parameter kanggo teks ing njero unsur kasebut. Kita kudu nggunakake metode ing teks. Nanging kepiye carane entuk informasi teks ing unsur yen iki cara sing beda? Solusiku: kita mung kudu ngelingi jeneng unsur pungkasan, lan charactersmriksa unsur sing kita maca informasi kasebut. Sampeyan uga kudu eling yen <codee>karakter maca kabeh karakter ing njero unsur, sing tegese kabeh spasi lan malah baris bakal diwaca. Lan kita ora butuh wong-wong mau. Kita kudu nglirwakake data iki amarga ora bener.</codee> Kode:
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;
            }
        }
    }
}
Minangka sampeyan bisa ndeleng, amarga komplikasi banal saka struktur file XML, kode kita dadi luwih rumit. Nanging, kode kasebut ora rumit. Katrangan: kita nggawe variabel kanggo nyimpen data babagan karyawan ( name, job) , uga variabel lastElementNamekanggo ngrekam unsur sing ana ing njero. Sawise iki, ing cara characterskita nyaring informasi, lan yen isih ana informasi, banjur iki tegese iki teks kita kudu, lan banjur nemtokake apa iku jeneng utawa Profesi nggunakake lastElementName. Ing cara endElement, kita mriksa yen kabeh informasi wis diwaca, lan yen ya, kita nggawe karyawan lan ngreset informasi kasebut. Output saka solusi padha karo conto pisanan:
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
Mangkono, masalah iki wis ditanggulangi , nanging sampeyan bisa sok dong mirsani sing kerumitan luwih. Mulane, kita bisa nyimpulake yen nyimpen informasi teks ing atribut bakal luwih bener tinimbang ing unsur individu. Lan siji tugas manis liyane sing sebagian bakal ngrampungake masalah ing JavaRush babagan nampilake informasi babagan unsur ing HTML, mung kudu diowahi sethithik, ing kene kita bakal dhaptar kabeh unsur ing njero unsur :) Tugas No 3 - diwenehi unsur unsur, nuduhake jeneng lan atribut kabeh unsur internal; yen unsur ora ketemu, nuduhake iki. Kanggo tugas iki, kita bakal nggunakake file XML ing ngisor iki:
<?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>
Nalika sampeyan bisa ndeleng, kita duwe telung kemungkinan skenario kene: root, mysql, oracle. Banjur program bakal nampilake kabeh informasi babagan kabeh unsur ing njero. Kepiye carane bisa nindakake iki? Lan cukup prasaja: kita mung kudu ngumumake variabel logis isEntered, sing bakal nuduhake yen kita butuh unsur ing njero, lan yen ana ing njero, maca kabeh data saka startElement. Kode solusi:
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;
        }
    }
}
Ing kode iki, nalika ngetik unsur sing mbutuhake informasi, kita nyetel gendéra isEntereddadi bener, sing tegese kita ana ing njero unsur kasebut. Lan sanalika kita ana ing njero unsur, kita mung ngolah saben unsur anyar startElement, ngerti manawa unsur kasebut minangka unsur internal. Dadi kita ngasilake jeneng unsur lan judhule. Yen unsur ora ditemokake ing file, banjur ana variabel isFoundsing disetel nalika unsur ditemokake, lan yen palsu, pesen bakal ditampilake yen unsur kasebut ora ditemokake. Lan sampeyan bisa ndeleng, ing conto SearchingXMLHandlerkita liwati rootunsur kanggo konstruktor. Kesimpulan kanggo dheweke:
Найден элемент <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
Mangkono, kita nampa kabeh informasi babagan unsur internal lan atribute. Masalah wis ditanggulangi. <h2>Epilog</h2>Sampeyan wis weruh yen SAX minangka alat sing cukup menarik lan cukup efektif, lan bisa digunakake kanthi cara sing beda-beda, kanggo tujuan sing beda-beda, lan liya-liyane, sampeyan mung kudu ndeleng masalah saka sisih tengen. sisih, minangka ditampilake ing tugas No.. 2 lan No.. 3, ngendi SAX ora nyedhiyani cara langsung kanggo mecahaken masalah, nanging, thanks kanggo kapinteran kita, kita bisa teka munggah karo cara metu saka kahanan. Bagian sabanjure artikel kasebut bakal dikhususake kanggo DOM. Muga-muga sampeyan seneng ngerti SAX. Eksperimen, laku lan sampeyan bakal ngerti yen kabeh iku cukup prasaja. Lan iku kabeh, apik luck karo program lan ngarepake bagean babagan DOM enggal. Sugeng sinau :) Artikel sadurunge: [Kompetisi] Dasar XML kanggo Programmer Java - Part 2 saka 3 Artikel sabanjure: [Kompetisi] Dasar XML kanggo Programmer Java - Part 3.2 saka 3 - DOM
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION