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

Java programmisti üçin XML esaslary. 3-nji bölümiň 3.2-nji bölümi - DOM

Toparda çap edildi
<h2> Giriş </h2> Makalanyň ähli okyjylaryna salam, bu bölüm DOM-a bagyşlanýar. Indiki biri JAXB-a bagyşlanar we munuň bilen XML esaslarynyň aýlawy tamamlanar. Ilki bilen azajyk teoriýa bolar, soň bolsa diňe amal ediler. Başlalyň. <h2> DOM (Resminamanyň obýekt modeli) - TEORI </A </h2> DOM işleýjisi, ähli XML-ni birbada okaýan we tygşytlaýan görnüşde aňsatlyk bilen hereket edip boljak agaç görnüşinde iýerarhiýa döredýär we zerur elementlere giriň. Şeýlelik bilen, ýokarky elemente baglanyşyk berip, onuň içki elementlerine ähli baglanyşyklary alyp bileris. Mundan başga-da, elementiň içindäki elementler bu elementiň çagalarydyr we bu olaryň ene-atasydyr. Xhli XML-ni ýatda saklanymyzdan soň, onuň gurluşyndan geçip, zerur hereketleri ýerine ýetireris. Java-daky DOM-yň programmirleme bölümi barada azajyk: DOM-da dürli maglumatlary beýan etmek üçin döredilen köp interfeýs bar. Bu interfeýsleriň hemmesi bir umumy interfeýsi - düwün. Sebäbi, aslynda, DOM-da iň köp ýaýran maglumatlar görnüşi, islendik zat bolup bilýän düwün. Her düwüniň maglumatlary almak üçin aşakdaky peýdaly usullary bar:
  1. getNodeName- öý eýesiniň adyny alyň.
  2. getNodeValue- düwün bahasyny alyň.
  3. getNodeType- düwün görnüşini alyň.
  4. getParentNode- berlen düwüniň ýerleşýän düwünini alyň.
  5. getChildNodes- alnan düwünleriň hemmesini alyň (berlen düwüniň içindäki düwünler).
  6. getAttributes- ähli düwün atributlaryny alyň.
  7. getOwnerDocument- bu düwüniň resminamasyny alyň.
  8. getFirstChild/getLastChild- ilkinji / soňky alnan düwün alyň.
  9. getLocalName- prefiksiz at almak üçin at giňişliklerini gaýtadan işlemekde peýdaly.
  10. getTextContent- elementiň içindäki ähli teksti we berlen elementiň içindäki ähli elementleri, şol sanda setir arakesmelerini we boşluklary yzyna gaýtaryp berýär.
9-njy usula bellik: At giňişligini gaýtadan işlemek üçin DocumentFactory-da setNamespaceAware (hakyky) usulyny ulanmasaňyz, elmydama null gaýdyp geler. Indi möhüm bir jikme-jiklik: usullar ähli düwünler üçin umumydyr, ýöne düwünde element hem, atribut hem bolup biler. Ine, soraglar: elementiň haýsy gymmaty bolup biler? Haýsy atributlara eýe bolup biler? Beýlekiler bolsa yzygiderli däl. Hemme zat gaty ýönekeý: her usul düwün görnüşine baglylykda işlär . Elbetde, bulaşmazlyk üçin logikany ulanmak ýeterlikdir. Mysal üçin: haýsy häsiýetlere eýe bolup bilýär? Elementiň başga manysy näme? Şeýle-de bolsa, hemme zady özüňiz synap görmezlik üçin resmi resminamalarda düwün görnüşine baglylykda her usulyň nähili işleýändigi barada örän peýdaly tablisa bar: Hil erbet boldy, şonuň üçin resminamalara baglanyşyk bar sahypanyň ýokarsy): düwün resminamalary Rememberatda saklamaly iň möhüm zat:
  1. Diňe elementleriň häsiýetleri bar.
  2. Elementleriň manysy ýok.
  3. Element düwüniniň ady belligiň ady bilen, atribut düwüniniň ady atributyň ady bilen deňdir.
<h2> DOM (Resminamanyň obýekt modeli) - TERJIME </h2> Amaly bölümde, XML-de maglumat gözlemek boýunça dürli meseleleri seljereris. Şeýle hem amatlylygy deňeşdirmek üçin öňki makaladan iki mesele aldyk. Başlalyň we importdan başlamak gowy bolardy:
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
Sapaklary bulaşdyrmazlyk üçin import edýärin :) 1-nji wezipe - ähli işgärler hakda maglumat almaly we aşakdaky XML faýlyndan konsola çykarmaly:
<?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>
Görşümiz ýaly, işgär elementlerinde saklanýan ähli maglumatlar bar. Programmamyzyň bir ýerinde saklamak üçin bir synp döredeliň 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;
    }
}
Maglumatlary saklamak üçin gurluşyň beýany bolansoň, işgärleri saklajak kolleksiýa gerek. Kodyň özünde dörederis. Şeýle hem, XML esasynda Resminama döretmeli:
public class DOMExample {
    // Список для сотрудников из XML file
    private static ArrayList<Employee> employees = new ArrayList<>();

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Получение фабрики, чтобы после получить билдер documentов.
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // Получor из фабрики билдер, который парсит XML, создает структуру Document в виде иерархического дерева.
        DocumentBuilder builder = factory.newDocumentBuilder();

        // Запарсor XML, создав структуру Document. Теперь у нас есть доступ ко всем elementм, Howим нам нужно.
        Document document = builder.parse(new File("resource/xml_file1.xml"));
    }
}
Resminamany alanymyzdan soň, XML faýlynyň ähli gurluşyna çäksiz güýjümiz bar. Islän wagtyňyz islendik elementi alyp bileris, islendik maglumatlary barlamak üçin we umuman, SAX-dakydan has çeýe çemeleşip bileris. Bu meseläniň çäginde diňe işgärleriň ähli elementlerini çykarmaly, soň bolsa olar hakda ähli maglumatlary çykarmaly. Bu gaty ýönekeý:
public class DOMExample {
    // Список для сотрудников из XML file
    private static ArrayList<Employee> employees = new ArrayList<>();

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Получение фабрики, чтобы после получить билдер documentов.
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // Получor из фабрики билдер, который парсит XML, создает структуру Document в виде иерархического дерева.
        DocumentBuilder builder = factory.newDocumentBuilder();

        // Запарсor XML, создав структуру Document. Теперь у нас есть доступ ко всем elementм, Howим нам нужно.
        Document document = builder.parse(new File("resource/xml_file1.xml"));

        // Получение списка всех элементов employee внутри корневого element (getDocumentElement возвращает ROOT элемент XML file).
        NodeList employeeElements = document.getDocumentElement().getElementsByTagName("employee");

        // Перебор всех элементов employee
        for (int i = 0; i < employeeElements.getLength(); i++) {
            Node employee = employeeElements.item(i);

            // Получение атрибутов каждого element
            NamedNodeMap attributes = employee.getAttributes();

            // Добавление сотрудника. Атрибут - тоже Node, потому нам нужно получить meaning атрибута с помощью метода getNodeValue()
            employees.add(new Employee(attributes.getNamedItem("name").getNodeValue(), attributes.getNamedItem("job").getNodeValue()));
        }

        // Вывод информации о каждом сотруднике
        for (Employee employee : employees)
            System.out.println(String.format("Информации о сотруднике: Name - %s, должность - %s.", employee.getName(), employee.getJob()));
    }
}
Bu çözgüdiň beýany çözgütde dogry. Kody görensoň, teoriýa dolanyp, täzeden okamak maslahat berilýär. Aslynda, hemme zat öz-özünden düşnükli. Teswirleri üns bilen okaň we soraglar bolmaly däl, soraglar bar bolsa teswirlerde ýazyp bilersiňiz, men jogap bererin ýa-da baglanyşykda ýa-da IDEA-ny işledip, kod bilen özüňiz oýnamaga synanyşyň entek etmediň Şonuň üçin kody işledenimizden soň 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.
Görşüňiz ýaly, wezipe üstünlikli tamamlandy! Indiki meselä geçeliň :) 2-nji wezipe - konsoldan bir elementiň ady girizilýär, bu hakda içindäki XML faýlyndaky ähli elementler we olaryň häsiýetleri barada maglumat görkezmeli:
<?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>
Hemme zat gaty ýönekeý: elementi hasaplaýan ady bilen almaly, soň bolsa çaga düwünlerinden geçmeli. Munuň üçin elementler bolan ähli çaga düwünleriniň çaga düwünleriniň üsti bilen gaýtalamaly. Bu meseläniň çözgüdi:
public class DOMExample {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Ридер для считывания имени тега из консоли
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        // Получение фабрики, чтобы после получить билдер documentов.
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // Получor из фабрики билдер, который парсит XML, создает структуру Document в виде иерархического дерева.
        DocumentBuilder builder = factory.newDocumentBuilder();

        // Запарсor XML, создав структуру Document. Теперь у нас есть доступ ко всем elementм, Howим нам нужно.
        Document document = builder.parse(new File("resource/xml_file3.xml"));

        // Считывание имени тега для поиска его в файле
        String element = reader.readLine();

        // Получение списка элементов, однако для удобства будем рассматривать только первое совпадение в documentе.
        // Так же заметьте, что мы ищем элемент внутри documentа, а не рут element. Это сделано для того, чтобы рут элемент тоже искался.
        NodeList matchedElementsList = document.getElementsByTagName(element);

        // Даже если element нет, всегда будет возвращаться список, просто он будет пустым.
        // Потому, чтобы утверждать, что element нет в файле, достаточно проверить размер списка.
        if (matchedElementsList.getLength() == 0) {
            System.out.println("Tag " + element + " не был найден в файле.");
        } else {
            // Получение первого element.
            Node foundedElement = matchedElementsList.item(0);

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

            // Если есть данные внутри, вызов метода для вывода всей информации
            if (foundedElement.hasChildNodes())
                printInfoAboutAllChildNodes(foundedElement.getChildNodes());
        }
    }

    /**
     * Рекурсивный метод, который будет выводить информацию про все узлы внутри всех узлов, которые пришли параметром, пока не будут перебраны все узлы.
     * @param list Список узлов.
     */
    private static void printInfoAboutAllChildNodes(NodeList list) {
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);

            // У элементов есть два вида узлов - другие элементы or текстовая информация. Потому нужно разбираться две ситуации отдельно.
            if (node.getNodeType() == Node.TEXT_NODE) {
                // Фильтрация информации, так How пробелы и переносы строчек нам не нужны. Это не информация.
                String textInformation = node.getNodeValue().replace("\n", "").trim();

                if(!textInformation.isEmpty())
                    System.out.println("Внутри element найден текст: " + node.getNodeValue());
            }
            // Если это не текст, а элемент, то обрабатываем его How элемент.
            else {
                System.out.println("Найден элемент: " + node.getNodeName() + ", его атрибуты:");

                // Получение атрибутов
                NamedNodeMap attributes = node.getAttributes();

                // Вывод информации про все атрибуты
                for (int k = 0; k < attributes.getLength(); k++)
                    System.out.println("Name атрибута: " + attributes.item(k).getNodeName() + ", его meaning: " + attributes.item(k).getNodeValue());
            }

            // Если у данного element еще остались узлы, то вывести всю информацию про все его узлы.
            if (node.hasChildNodes())
                printInfoAboutAllChildNodes(node.getChildNodes());
        }
    }
}
Çözüwiň ähli beýany teswirlerde, ýöne teoriýadan bir suratdan mysal alyp, ulanan çemeleşmämizi birneme grafiki taýdan görkezmek isleýärin. Html belligi barada maglumatlary görkezmelidigimizi kabul ederis. Görşüňiz ýaly agajyň kökünden ýokardan aşaklygyna gitmeli. Linehli setirler düwünlerdir. Çözüwde, ähli düwünleriň üsti bilen islenýän elementiň başyndan yzygiderli geçeris we düwünleriniň biri element bolsa, bu elementiň ähli düwünlerini hem gaýtalaýarys. Şonuň üçin kod işledilenden soň kök elementi üçin aşakdaky netijäni aldyk:
Элемент был найден!
Найден элемент: 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
Mesele üstünlikli çözüldi! 3-nji wezipe - talyplar, professorlar we işgärler baradaky maglumatlar saklanýan aşakdaky XML faýlyndan, maglumatlary okamaly we konsola çykarmaly:
<?xml version="1.0" encoding="UTF-8"?>
<database>
    <students>
        <student name="Maksim" course="3" specialization="CE" />
        <student name="Stephan" course="1" specialization="CS" />
        <student name="Irvin" course="2" specialization="CE" />
    </students>

    <professors>
        <professor name="Herald" experience="7 years in University" discipline="Math" />
        <professor name="Adam" experience="4 years in University" discipline="Programming" />
        <professor name="Anton" experience="6 years in University" discipline="English" />
    </professors>

    <service>
        <member name="John" position="janitor" />
        <member name="Jordan" position="janitor" />
        <member name="Mike" position="janitor" />
    </service>
</database>
Wezipe gaty ýönekeý, ýöne gyzykly. Ilki bilen, 4 synp döretmeli: işgär, professor we okuwçy, şeýle hem umumy abstrakt synp Adam, her synpdan adyň üýtgeýjisini umumy bir bellige almak üçin: Abstrakt ene synpy
public abstract class Human {
    private String name;

    public Human(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
Talyp
public class Student extends Human {
    private String course, specialization;

    public Student(String name, String course, String specialization) {
        super(name);
        this.course = course;
        this.specialization = specialization;
    }

    public String getCourse() {
        return course;
    }

    public String getSpecialization() {
        return specialization;
    }

    public String toString() {
        return "Голодный студент " + getName() + " " + course + "-го курса, обучающийся по специальности " + specialization;
    }
}
Professor
public class Professor extends Human {
    private String experience, discipline;

    public Professor(String name, String experience, String discipline) {
        super(name);
        this.experience = experience;
        this.discipline = discipline;
    }

    public String getExperience() {
        return experience;
    }

    public String getDiscipline() {
        return discipline;
    }

    public String toString() {
        return "Профессор " + getName() + ", обладающий опытом: \"" + experience + "\", выкладает дисциплину " + discipline;
    }
}
Işgär
public class Member extends Human {
    private String position;

    public Member(String name, String position) {
        super(name);
        this.position = position;
    }

    public String getPosition() {
        return position;
    }

    public String toString() {
        return "Сотрудник обслуживающего персонала " + getName() + ", должность: " + position;
    }
}
Indi sapaklarymyz taýýar bolansoň, ähli elementleri talyp, professor we agza almak üçin kod ýazmaly, soň bolsa häsiýetlerini almaly. Saklamak üçin, hemmeler üçin umumy bolan ene-atanyň obýektlerini saklaýan kolleksiýany ulanarys. Şeýlelik bilen, bu meseläniň çözgüdi:
public class DOMExample {
    // Коллекция для хранения всех людей
    private static ArrayList<Human> humans = new ArrayList<>();

    // Константы для элементов
    private static final String PROFESSOR = "professor";
    private static final String MEMBER = "member";
    private static final String STUDENT = "student";

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        // Получение фабрики, чтобы после получить билдер documentов.
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // Получor из фабрики билдер, который парсит XML, создает структуру Document в виде иерархического дерева.
        DocumentBuilder builder = factory.newDocumentBuilder();

        // Запарсor XML, создав структуру Document. Теперь у нас есть доступ ко всем elementм, Howим нам нужно.
        Document document = builder.parse(new File("resource/xml_file3.xml"));

        // Получение информации про каждый элемент отдельно
        collectInformation(document, PROFESSOR);
        collectInformation(document, MEMBER);
        collectInformation(document, STUDENT);

        // Вывод информации
        humans.forEach(System.out::println);
    }

    /**
     * Метод ищет информацию про теги по имени element и вносит всю информацию в коллекцию humans.
     * @param document Документ, в котором будем искать элементы.
     * @param element Name element, теги которого нужно найти. Должна быть одна из констант, которые определяются выше.
     */
    private static void collectInformation(Document document, final String element) {
        // Получение всех элементов по имени тега.
        NodeList elements = document.getElementsByTagName(element);

        // Перебор всех найденных элементов
        for (int i = 0; i < elements.getLength(); i++) {
            // Получение всех атрибутов element
            NamedNodeMap attributes = elements.item(i).getAttributes();
            String name = attributes.getNamedItem("name").getNodeValue();

            // В зависимости от типа element, нам нужно собрать свою дополнительну информацию про каждый подкласс, а после добавить нужные образцы в коллекцию.
            switch (element) {
                case PROFESSOR: {
                    String experience = attributes.getNamedItem("experience").getNodeValue();
                    String discipline = attributes.getNamedItem("discipline").getNodeValue();

                    humans.add(new Professor(name, experience, discipline));
                } break;
                case STUDENT: {
                    String course = attributes.getNamedItem("course").getNodeValue();
                    String specialization = attributes.getNamedItem("specialization").getNodeValue();

                    humans.add(new Student(name, course, specialization));
                } break;
                case MEMBER: {
                    String position = attributes.getNamedItem("position").getNodeValue();

                    humans.add(new Member(name, position));
                } break;
            }
        }
    }
}
Bu elementleriň hemmesini resminamadan almak üçin diňe elementiň adynyň gerekdigini unutmaň. Bu size zerur maglumatlary tapmak prosesini ep-esli aňsatlaşdyrýar. Kod baradaky ähli maglumatlar teswirlerde bar. Öňki meselelerde ýok täze zat ulanylmady. Kod çykarylyşy:
Профессор Herald, обладающий опытом: "7 years in University", выкладает дисциплину Math
Профессор Adam, обладающий опытом: "4 years in University", выкладает дисциплину Programming
Профессор Anton, обладающий опытом: "6 years in University", выкладает дисциплину English
Сотрудник обслуживающего персонала John, должность: janitor
Сотрудник обслуживающего персонала Jordan, должность: janitor
Сотрудник обслуживающего персонала Mike, должность: janitor
Голодный студент Maksim 3-го курса, обучающийся по специальности CE
Голодный студент Stephan 1-го курса, обучающийся по специальности CS
Голодный студент Irvin 2-го курса, обучающийся по специальности CE
Mesele çözüldi! DOM-ny haçan ulanmalydygy we SAX-ny haçan ulanmalydygy barada maslahatlar Bu gurallaryň arasyndaky tapawut işleýiş we tizlikde. Has çeýe işlemäge mätäç bolsaňyz we programmanyň işleýşini ýitirip bilýän bolsaňyz, onda siziň saýlamagyňyz DOM, ýöne esasy maksadyňyz ýat çykdajylaryny azaltmak bolsa, DOM iň gowy saýlaw däl, sebäbi XML faýlyndaky ähli maglumatlary okaýar we saklaýar. Şonuň üçin SAX yzygiderli okamak usuly has arzan. Gysgaça: öndürijilik gerek bolsa - SAX, işleýiş - DOM. <h2> Netije </h2> Her bir programmistiň öz gurallary bar we meselä baglylykda belli gurallary ulanmaly. SAX we DOM baradaky makalalarda, maksadym size XML faýllaryndan maglumatlary nädip çykarmalydygyny we olary zerur görnüşde gaýtadan işlemegi öwretmekdi. Şeýle-de bolsa, bu makalalary okan bolsaňyzam, bu gurallary ulanmagy öwrenendigiňizi aýdyp bilmersiňiz. Amal etmeli, makalalardan kody barlamaly, işleýşine düşünmeli we özüň bir zat ýazmaga synanyşmaly. Galyberse-de, iň möhüm zat tejribe. Iň soňky makala ýakyn günlerde çap ediler we, bäsleşik gutarandan soň, JAXB-a bagyşlanar. JAXB programmaňyzdaky zatlary XML formatda saklamak üçin guraldyr. Bularyň hemmesi, bu makalanyň peýdalydygyna we programma üpjünçiligiňizde üstünlik arzuw edýärin :) Öňki makala: [Bäsdeşlik] Java programmisti üçin XML esaslary - 3-nji bölümiň 3.1 bölümi - SAX
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION