JavaRush /Blog Java /Random-PL /Podstawy XML dla programisty Java. Część 2 z 3
Ярослав
Poziom 40
Днепр

Podstawy XML dla programisty Java. Część 2 z 3

Opublikowano w grupie Random-PL

Wstęp

Witam, drodzy czytelnicy mojego artykułu. To drugi artykuł z serii o XML, a w tym artykule omówimy przestrzeń nazw XML i schemat XML.
Podstawy XML-a
Jeszcze niedawno sam nic o tym nie wiedziałem, ale opanowałem sporo materiału i postaram się w prostych słowach wyjaśnić te dwa ważne tematy. Od razu chcę powiedzieć, że schematy są bardzo zaawansowanym mechanizmem walidacji dokumentów XML i są znacznie bardziej funkcjonalne niż DTD, dlatego nie będzie tutaj ich pełnego badania. Zacznijmy :)

Przestrzeń nazw XML

Przestrzeń nazw oznacza „przestrzeń nazw”, jednak w tym artykule często będę zastępować rosyjskie wyrażenie po prostu przestrzenią nazw, ponieważ jest krótsza i łatwiejsza do zrozumienia. XML Namespace to technologia, której głównym celem jest upewnienie się, że wszystkie elementy w pliku XML są unikalne i nie ma pomyłek. A ponieważ są to kursy Java, ta sama technologia jest dostępna również w pakietach Java. Gdybyśmy mogli umieścić obok siebie dwie klasy o tej samej nazwie i używać ich, jak określilibyśmy, której klasy potrzebujemy? Problem ten rozwiązują pakiety - możemy po prostu umieścić klasy w różnych pakietach i stamtąd je zaimportować, podając dokładną nazwę żądanego pakietu i ścieżkę do niego lub po prostu podając pełną ścieżkę do żądanej klasy. Podstawy XML dla programisty Java.  Część 2 z 3 - 1Teraz możemy to zrobić:
public class ExampleInvocation {
    public static void main(String[] args) {
        // kreacja экземпляра класса из первого пакета.
        example_package_1.Example example1 = new example_package_1.Example();

        // kreacja экземпляра класса из второго пакета.
        example_package_2.Example example2 = new example_package_2.Example();

        // kreacja экземпляра класса из третьего пакета.
        example_package_3.Example example3 = new example_package_3.Example();
    }
}
W przestrzeni nazw XML wszystko jest prawie takie samo, tylko trochę inne. Istota jest taka sama: jeśli elementy są takie same (jak klasy), to wystarczy, że zastosujemy je w różnych przestrzeniach nazw (określ pakiety), to nawet jeśli nazwy elementów (klas) zaczną się pokrywać, nadal będziemy uzyskać dostęp do określonego elementu z przestrzeni (pakiet). Na przykład: mamy dwa elementy w XML - predykcję (oracle) i bazę danych Oracle.
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <oracle>
        <connection value="jdbc:oracle:thin:@10.220.140.48:1521:test1" />
        <user value="root" />
        <password value="111" />
    </oracle>

    <oracle>
        Сегодня вы будете заняты весь день.
    </oracle>
</root>
A kiedy będziemy przetwarzać ten plik XML, będziemy poważnie zdezorientowani, jeśli zamiast bazy danych otrzymamy prognozę i odwrotnie. Aby rozwiązać kolizję elementów, możemy przydzielić każdemu z nich własną przestrzeń w celu ich rozróżnienia. Służy do tego specjalny atrybut – xmlns:prefix= „unikalna wartość dla przestrzeni nazw”. Możemy następnie poprzedzić elementy, aby wskazać, że są one częścią tej przestrzeni nazw (zasadniczo musimy utworzyć ścieżkę pakietu - przestrzeń nazw, a następnie poprzedzić każdy element, do którego pakietu należy).
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <database:oracle xmlns:database="Unique ID #1">
        <connection value="jdbc:oracle:thin:@10.220.140.48:1521:test1" />
        <user value="root" />
        <password value="111" />
    </database:oracle>

    <oracle:oracle xmlns:oracle="Unique ID #2">
        Сегодня вы будете заняты весь день.
    </oracle:oracle>
</root>
W tym przykładzie zadeklarowaliśmy dwie przestrzenie nazw: bazę danych i Oracle. Teraz możesz używać przedrostków przestrzeni nazw przed elementami. Nie ma powodu się bać, jeśli coś jest teraz niejasne. W rzeczywistości jest to bardzo proste. Początkowo chciałem szybciej napisać tę część artykułu, ale po środzie zdecydowałem, że muszę poświęcić temu tematowi więcej uwagi, bo łatwo się pomylić lub czegoś nie zrozumieć. Teraz dużo uwagi zostanie poświęcone atrybutowi xmlns. I tak kolejny przykład:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.fish-shop.com/">
    <gun:shop>
        <gun:guns>
            <gun:gun name="Revolver" price="1250$" max_ammo="7" />
            <gun:gun name="M4A1" price="3250$" max_ammo="30" />
            <gun:gun name="9mm Pistol" price="450$" max_ammo="12" />
        </gun:guns>
    </gun:shop>

    <fish:shop>
        <fish:fishes>
            <fish:fish name="Shark" price="1000$" />
            <fish:fish name="Tuna" price="5$" />
            <fish:fish name="Capelin" price="1$" />
        </fish:fishes>
    </fish:shop>
</root>
Możesz zobaczyć zwykły kod XML używający spacji pistolet do przechowywania unikalnych elementów broni i ryb do przechowywania unikalnych elementów dla wędkarzy. Widać, że tworząc przestrzenie, wykorzystaliśmy jeden element sklepu do dwóch różnych rzeczy na raz - sklepu z bronią i sklepu z rybami, a wiemy dokładnie, jaki to rodzaj sklepu, dzięki temu, że zadeklarowaliśmy przestrzenie. Najciekawsze zaczniemy na schematach, kiedy będziemy mogli w ten sposób walidować różne konstrukcje z tymi samymi elementami. xmlns to atrybut służący do deklarowania przestrzeni nazw; można go określić w dowolnym elemencie. Przykład deklaracji przestrzeni nazw:
xmlns:shop= «https://barber-shop.com/»
Po dwukropku znajduje się przedrostek – jest to odniesienie do spacji, którego można następnie użyć przed elementami, aby wskazać, że pochodzą one z tej spacji. Wartość xmlns musi być UNIKALNYM ŁAŃCUCHEM. Jest to niezwykle ważne, aby zrozumieć: bardzo często używa się łączy do witryn internetowych lub identyfikatorów URI w celu zadeklarowania przestrzeni nazw. Ta reguła jest standardowa, ponieważ URI lub URL łącza jest unikalny, ALE w tym przypadku robi się bardzo zagmatwane. Pamiętaj tylko: wartością może być DOWOLNY ciąg znaków, ale aby mieć pewność, że jest on unikalny i standardowy, musisz użyć adresu URL lub URI. Fakt, że można użyć dowolnych ciągów znaków pokazano na przykładzie w Oracle:
xmlns:oracle="Unique ID #2"
xmlns:database="Unique ID #1"
Kiedy deklarujesz przestrzeń nazw, możesz jej użyć na samym elemencie i na wszystkich elementach w nim zawartych, więc przestrzenie nazw zadeklarowane w elemencie głównym mogą być używane na wszystkich elementach. Można to zobaczyć w ostatnim przykładzie, a oto bardziej szczegółowy przykład:
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <el1:element1 xmlns:el1="Element#1 Unique String">
        <el1:innerElement>

        </el1:innerElement>
    </el1:element1>


    <el2:element2 xmlns:el2="Element#2 Unique String">
        <el2:innerElement>

        </el2:innerElement>
    </el2:element2>


    <el3:element3 xmlns:el3="Element#3 Unique String">
        <el3:innerElement>
            <el1:innerInnerElement> <!-- Так нельзя, потому что пространство el1 объявлено только в первом элементе, потому может использовать только внутри первого element и его внутренних элементов. -->

            </el1:innerInnerElement>
        </el3:innerElement>
    </el3:element3>
</root>
Oto ważny szczegół: w elemencie głównym znajduje się również standardowa przestrzeń nazw. Jeśli zadeklarujesz inne przestrzenie nazw, nadpiszesz domyślną i nie będziesz mógł jej używać. Następnie musisz umieścić jakiś przedrostek spacji przed elementem głównym, dowolny, który zadeklarowałeś wcześniej. Można to jednak również oszukać: możesz jawnie zadeklarować standardową przestrzeń. Wystarczy nie używać przedrostka po xmlns, ale od razu zapisać jakąś wartość, a wszystkie Twoje elementy bez przedrostka będą należeć do tej konkretnej przestrzeni nazw. W ostatnim przykładzie użyto tego:
<root xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.fish-shop.com/">
Wyraźnie zadeklarowaliśmy standardową przestrzeń, aby uniknąć konieczności użycia broni lub ryby, ponieważ element główny nie jest podmiotem ani sklepu wędkarskiego, ani broni, więc użycie którejkolwiek przestrzeni byłoby logicznie niepoprawne. Dalej: jeśli utworzyłeś xmlns:a i xmlns:b, ale mają one tę samą wartość, to jest to ta sama przestrzeń i nie są one unikalne. Dlatego zawsze powinieneś używać unikalnych wartości, ponieważ naruszenie tej zasady może spowodować dużą liczbę błędów. Na przykład, gdybyśmy zadeklarowali spacje w ten sposób:
xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.gun-shop.com/"
Wtedy nasz sklep wędkarski stałby się sklepem z bronią, a przedrostek nadal byłby sklepem rybnym. To są wszystkie główne punkty przestrzeni. Spędziłem sporo czasu, zbierając je wszystkie i redukując, a następnie jasno je wyrażając, ponieważ informacje w przestrzeniach w Internecie są bardzo duże i często to tylko woda, więc większość wszystkiego, co tu jest - nauczyłem się tego sam podczas prób i błąd. Jeśli nadal masz pytania, możesz spróbować zapoznać się z materiałami, korzystając z linków na końcu artykułu.

Schemat XML

Od razu chcę powiedzieć, że ten artykuł będzie tylko wierzchołkiem góry lodowej, ponieważ temat jest bardzo szeroki. Jeśli chcesz bardziej szczegółowo zapoznać się ze schematami i dowiedzieć się, jak samodzielnie je napisać o dowolnej złożoności, na końcu artykułu pojawi się link, w którym wszystko będzie dotyczyło różnych typów, ograniczeń, rozszerzeń i tak dalej. Chcę zacząć od teorii. Schematy mają format .xsd (definicja schematu XML) i są bardziej zaawansowaną i popularną alternatywą dla DTD: umożliwiają także tworzenie elementów, opisywanie ich itd. Jednakże dodano wiele bonusów: sprawdzanie typów, obsługę przestrzeni nazw i szerszą funkcjonalność. Pamiętasz, kiedy rozmawialiśmy o DTD, był minus, że nie obsługuje spacji? Teraz, gdy już to przestudiowaliśmy, wyjaśnię: gdyby można było zaimportować dwa lub więcej schematów z DTD, w których byłyby identyczne elementy, mielibyśmy kolizje (zbiegi okoliczności) i w ogóle nie moglibyśmy ich użyć, ponieważ nie jest jasne, jakiego elementu potrzebujemy. XSD rozwiązuje ten problem, ponieważ możesz importować schematy do jednej określonej przestrzeni i używać ich. Zasadniczo każdy schemat XSD ma przestrzeń docelową, co oznacza, w której przestrzeni schemat powinien zostać zapisany w pliku XML. Zatem w samym pliku XML wystarczy utworzyć te spacje predefiniowane w schematach i przypisać do nich przedrostki, a następnie do każdego z nich podłączyć niezbędne schematy, po czym będziemy mogli bezpiecznie korzystać z elementów ze schematu, podstawiając przedrostki z miejsce, do którego zaimportowaliśmy schematy. I tak mamy przykład:
<?xml version="1.0" encoding="UTF-8"?>
<house>
    <address>ул. Есенина, дом №5</address>
    <owner name="Ivan">
        <telephone>+38-094-521-77-35</telephone>
    </owner>
</house>
Chcemy to zweryfikować za pomocą schematu. Najpierw potrzebujemy schematu:
<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="https://www.nedvigimost.com/">
    <element name="house">
        <complexType>
            <sequence>
                <element name="address" type="string" maxOccurs="unbounded" minOccurs="0" />
                <element name="owner" maxOccurs="unbounded" minOccurs="0" >
                    <complexType>
                        <sequence>
                            <element name="telephone" type="string" />
                        </sequence>
                        <attribute name="name" type="string" use="required"/>
                    </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>
Jak widać schematy są również plikami XML. Piszesz to, czego potrzebujesz bezpośrednio w formacie XML. Ten schemat umożliwia sprawdzenie poprawności pliku XML z powyższego przykładu. Na przykład: jeśli właściciel nie ma imienia, obwód to zobaczy. Ponadto, dzięki elementowi sekwencji, zawsze na pierwszym miejscu powinien znajdować się adres, a dopiero potem właściciel domu. Istnieją elementy zwykłe i złożone. Elementy regularne to elementy przechowujące tylko określony typ danych. Przykład:
<element name="telephone" type="string" />
W ten sposób deklarujemy element przechowujący ciąg znaków. Wewnątrz tego elementu nie powinny znajdować się żadne inne elementy. Istnieją również elementy złożone. Złożone elementy są w stanie przechowywać w sobie inne elementy i atrybuty. Wtedy nie musisz określać typu, ale po prostu zacznij pisać typ złożony wewnątrz elementu.
<complexType>
    <sequence>
        <element name="address" type="string" maxOccurs="unbounded" minOccurs="0" />
        <element name="owner" maxOccurs="unbounded" minOccurs="0" >
            <complexType>
                <sequence>
                    <element name="telephone" type="string" />
                </sequence>
                <attribute name="name" type="string" use="required"/>
            </complexType>
        </element>
    </sequence>
</complexType>
Można było też zrobić to inaczej: można było utworzyć typ złożony osobno, a następnie zastąpić go typem. Tylko pisząc ten przykład z jakiegoś powodu trzeba było zadeklarować spację pod jakimś przedrostkiem, a nie używać standardowego. Ogólnie wyszło tak:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="https://www.nedvigimost.com/">
    <xs:element name="house" type="content" />

    <xs:complexType name="content">
        <xs:sequence>
            <xs:element name="address" type="xs:string" maxOccurs="unbounded" minOccurs="0" />
            <xs:element name="owner" maxOccurs="unbounded" minOccurs="0" >
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="telephone" type="xs:string" />
                    </xs:sequence>
                    <xs:attribute name="name" type="xs:string" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
W ten sposób możemy osobno utworzyć własne typy, a następnie zastąpić je gdzieś w atrybucie type. Jest to bardzo wygodne, ponieważ pozwala na użycie jednego typu w różnych miejscach. Chciałbym porozmawiać więcej na temat łączenia obwodów i zakończyć w tym miejscu. Istnieją dwa sposoby podłączenia obwodu: w określoną przestrzeń i po prostu podłącz.

Pierwszy sposób podłączenia obwodu

Pierwsza metoda zakłada, że ​​obwód ma określoną przestrzeń docelową. Jest ona określana przy użyciu atrybutu targetNamespace w elemencie schematu. Następnie wystarczy stworzyć TĘ SAMĄ przestrzeń w pliku XML, a następnie „załadować” tam schemat:
<?xml version="1.0" encoding="UTF-8"?>
<nedvig:house xmlns:nedvig="https://www.nedvigimost.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.nedvigimost.com/ example_schema1.xsd">
    <address>ул. Есенина, дом №5</address>
    <owner name="Ivan">
        <telephone>+38-094-521-77-35</telephone>
    </owner>
</nedvig:house>
Ważne jest, aby zrozumieć dwie linie:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemeLocation="https://www.nedvigimost.com/ example_schema1.xsd"
Pierwsza linijka – po prostu ją zapamiętaj. Pomyśl o tym jak o obiekcie, który pomaga załadować schematy tam, gdzie są potrzebne. Druga linia to konkretny plik do pobrania. schemaLocation akceptuje listę wartości w postaci „wartość - wartość”, oddzielonych spacją. Pierwszym argumentem jest przestrzeń nazw, która musi odpowiadać docelowej przestrzeni nazw w schemacie (wartość targetNamespace). Drugi argument to względna lub bezwzględna ścieżka do schematu. A ponieważ jest to wartość LISTA, możesz wstawić spację po schemacie z przykładu i ponownie wpisać docelową spację oraz nazwę innego schematu i tak dalej, ile chcesz. Ważny:Aby schemat mógł coś później sprawdzić, musisz zadeklarować tę spację i użyć jej z prefiksem. Przyjrzyj się uważnie ostatniemu przykładowi:
<?xml version="1.0" encoding="UTF-8"?>
<nedvig:house xmlns:nedvig="https://www.nedvigimost.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.nedvigimost.com/ example_schema1.xsd">
    <address>ул. Есенина, дом №5</address>
    <owner name="Ivan">
        <telephone>+38-094-521-77-35</telephone>
    </owner>
</nedvig:house>
Stworzyliśmy tę przestrzeń docelową na przedrostku nedvig, a następnie ją wykorzystaliśmy. Tym samym zaczęto walidować nasze elementy, gdyż zaczęliśmy wykorzystywać przestrzeń, w której odwołuje się do docelowej przestrzeni schematu.

Drugi sposób podłączenia obwodu

Drugi sposób podłączenia obwodu zakłada, że ​​obwód nie ma określonej przestrzeni docelowej. Następnie możesz po prostu podłączyć go do pliku XML, a on go sprawdzi. Odbywa się to prawie w ten sam sposób, z tą różnicą, że w pliku XML nie można w ogóle deklarować spacji, a jedynie połączyć schemat.
<?xml version="1.0" encoding="UTF-8"?>
<house xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="example_schema1.xsd">
    <address>ул. Есенина, дом №5</address>
    <owner name="Ivan">
        <telephone>+38-094-521-77-35</telephone>
    </owner>
</house>
Jak widać, odbywa się to za pomocą noNamespaceSchemaLocation i określenia ścieżki do schematu. Nawet jeśli schemat nie ma przestrzeni docelowej, dokument zostanie zweryfikowany. I ostatni akcent: możemy importować inne diagramy do diagramów, a następnie wykorzystywać elementy z jednego diagramu w innym. Dzięki temu w jednych obwodach możemy wykorzystać elementy, które już znajdują się w innych. Przykład:

Schemat, w którym zadeklarowany jest typ właściciela:

<?xml version="1.0" encoding="UTF-8" ?>
<schema targetNamespace="bonus" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
        <complexType name="owner">
            <all>
                <element name="telephone" type="string" />
            </all>
            <attribute name="name" type="string" />
        </complexType>
</schema>

Drugi schemat, który wykorzystuje typ właściciela z pierwszego schematu:

<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="main" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:bonus="bonus" elementFormDefault="qualified">
    <import namespace="bonus" schemaLocation="xsd2.xsd" />
    <element name="house">
        <complexType>
            <all>
              <element name="address" type="string" />
                <element name="owner" type="bonus:owner" />
            </all>
        </complexType>
    </element>
</schema>
Drugi schemat wykorzystuje następującą konstrukcję:
<import namespace="bonus" schemaLocation="xsd2.xsd" />
Za jego pomocą importowaliśmy typy i elementy z jednego schematu do drugiego do przestrzeni bonusowej. Tym samym mamy dostęp do bonusu: typ właściciela. W następnym wierszu użyliśmy go:
<element name="owner" type="bonus:owner" />
Zwróćmy także uwagę na następujący wiersz:
elementFormDefault="qualified"
Atrybut ten jest zadeklarowany w schemacie i oznacza, że ​​w plikach XML każdy element musi być zadeklarowany z wyraźnym przedrostkiem. Jeśli go tam nie ma, to wystarczy zadeklarować element zewnętrzny z przedrostkiem, a także ustawić przedrostki we wszystkich elementach wewnątrz, wyraźnie wskazując, że używamy dokładnie elementów tego schematu. A oto przykład pliku XML zweryfikowanego przez schemat, który zaimportował inny schemat:
<?xml version="1.0" encoding="UTF-8"?>
<nedvig:house xmlns:nedvig="main" xmlns:bonus="bonus" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="main xsd.xsd">
    <nedvig:address>ул. Есенина, дом №5</nedvig:address>
    <nedvig:owner name="Ivan">
        <bonus:telephone>+38-094-521-77-35</bonus:telephone>
    </nedvig:owner>
</nedvig:house>
W linii:
<bonus:telephone>+38-094-521-77-35</bonus:telephone>
Musimy jawnie zadeklarować dodatkową przestrzeń nazw, która wskazuje przestrzeń docelową pierwszego schematu, ponieważ elementFormDefault jest kwalifikowany (zaznacz), więc wszystkie elementy muszą jawnie wskazywać swoją przestrzeń.

Koniec artykułu

Następny artykuł będzie ostatnim z serii i już będzie dotyczył przetwarzania plików XML przy użyciu języka Java. Nauczymy się pozyskiwać informacje na różne sposoby i tak dalej. Mam nadzieję, że ten artykuł był przydatny i nawet jeśli gdzieś są błędy, nauczy Cię czegoś przydatnego i nowego, a może po prostu da ci możliwość lepszego zrozumienia plików XML. Dla tych, którzy chcieliby zgłębić ten temat bardziej szczegółowo, zdecydowałem się przygotować mały zestaw linków:
  • Proste elementy XSD - zaczynając od tego artykułu, zacznij czytać i idź dalej, wszystkie informacje o schematach są tam zebrane i wyjaśnione mniej lub bardziej przejrzyście, tylko w języku angielskim. Możesz skorzystać z tłumacza.

  • wideo na temat przestrzeni nazw, zawsze warto wysłuchać innego punktu widzenia na jakiś temat, jeśli pierwszy nie jest jasny.

  • XML przestrzeni nazw jest dobrym przykładem wykorzystania przestrzeni nazw i jest dość wszechstronny.

  • Podstawy XML - Przestrzenie nazw - Kolejny krótki artykuł na temat przestrzeni nazw.

  • Podręcznik Podstawy używania schematu XML do definiowania elementów jest również niezwykle przydatnym podręcznikiem dotyczącym schematów, ale trzeba go czytać powoli i uważnie, zagłębiając się w materiał.

To wszystko na pewno, mam nadzieję, że jeśli chcesz dowiedzieć się z tego czegoś głębszego, linki Ci pomogą. Sam przejrzałem wszystkie te źródła, przestudiowałem cały materiał i w sumie były one najbardziej przydatne ze wszystkich źródeł, z których korzystałem, ponieważ każde z nich albo poprawiło zrozumienie tego, co już gdzieś przeczytałem, albo pozwól mi nauczyć się czegoś nowego, ale wiele zostało zrobione właśnie podczas ćwiczeń. Zatem dla tych, którzy naprawdę chcą to wszystko dobrze zrozumieć, moja rada jest następująca: przestudiuj przestrzenie nazw, następnie jak łatwo połączyć schematy z plikami XML, a następnie jak zapisać strukturę dokumentu w schematach. A co najważniejsze, ćwicz. Dziękuję wszystkim za uwagę i życzę powodzenia w programowaniu :) Poprzedni artykuł: [Konkurs] Podstawy XML dla programisty Java - część 1 z 3 Następny artykuł: [Konkurs] Podstawy XML dla programisty Java - część 3.1 z 3 - SAX
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION