JavaRush /Blog Java /Random-FR /Bases XML pour programmeur Java. Partie 2 sur 3
Ярослав
Niveau 40
Днепр

Bases XML pour programmeur Java. Partie 2 sur 3

Publié dans le groupe Random-FR

Introduction

Bonjour, chers lecteurs de mon article. Il s'agit du deuxième article de la série sur XML, et cet article parlera de l'espace de noms XML et du schéma XML.
Notions de base sur XML
Tout récemment, je n'en savais rien moi-même, mais j'ai maîtrisé beaucoup de matière et je vais essayer d'expliquer ces deux sujets importants avec des mots simples. Je tiens à dire tout de suite que les schémas sont un mécanisme très avancé pour valider les documents XML et sont beaucoup plus fonctionnels que les DTD, il n'y en aura donc pas une étude complète ici. Commençons :)

Espace de noms XML

Namespace signifie « espace de noms », mais dans cet article, je remplacerai souvent l'expression russe par simplement espace de noms, car elle est plus courte et plus pratique à comprendre. XML Namespace est une technologie dont l'objectif principal est de garantir que tous les éléments sont uniques dans un fichier XML et qu'il n'y a pas de confusion. Et comme il s’agit de cours Java, la même technologie est également disponible dans les packages Java. Si nous pouvions placer deux classes portant le même nom l’une à côté de l’autre et les utiliser, comment déterminerions-nous de quelle classe nous avons besoin ? Ce problème est résolu par les packages - nous pouvons simplement placer des classes dans différents packages et les importer à partir de là, en spécifiant le nom exact du package souhaité et le chemin d'accès à celui-ci, ou simplement en spécifiant le chemin complet vers la classe souhaitée. Bases XML pour programmeur Java.  Partie 2 sur 3 - 1Maintenant, nous pouvons faire ceci :
public class ExampleInvocation {
    public static void main(String[] args) {
        // Creation экземпляра класса из первого пакета.
        example_package_1.Example example1 = new example_package_1.Example();

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

        // Creation экземпляра класса из третьего пакета.
        example_package_3.Example example3 = new example_package_3.Example();
    }
}
Dans XML Namespace, tout est à peu près pareil, juste un peu différent. L'essence est la même : si les éléments sont les mêmes (comme les classes), alors nous devons simplement les utiliser dans des espaces de noms différents (préciser les packages), alors même si les noms des éléments (classes) commencent à coïncider, nous le ferons toujours accéder à un élément spécifique depuis l'espace ( package ). Par exemple : nous avons deux éléments en XML : la prédiction (oracle) et la base de données 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>
Et lorsque nous traiterons ce fichier XML, nous serons sérieusement confus si, au lieu de la base de données, nous recevons une prédiction, et inversement. Afin de résoudre la collision d'éléments, nous pouvons attribuer à chacun d'eux son propre espace pour les différencier. Il existe un attribut spécial pour cela – xmlns:prefix= « valeur unique pour l'espace de noms ». Nous pouvons ensuite préfixer les éléments pour indiquer qu'ils font partie de cet espace de noms (essentiellement, nous devons créer un chemin de package - espace de noms, puis préfixer chaque élément avec le package auquel il appartient).
<?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>
Dans cet exemple, nous avons déclaré deux espaces de noms : base de données et oracle. Vous pouvez désormais utiliser des préfixes d'espace de noms avant les éléments. Il n’y a pas lieu d’avoir peur si quelque chose n’est pas clair maintenant. En fait, c'est très simple. Au début, je voulais écrire cette partie de l'article plus rapidement, mais après mercredi, j'ai décidé que je devais accorder plus d'attention à ce sujet, car il est facile de se tromper ou de ne pas comprendre quelque chose. Désormais, une grande attention sera accordée à l'attribut xmlns. Et donc, un autre exemple :
<?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>
Vous pouvez voir le XML normal en utilisant les éléments uniques du magasin d'armes à feu Spaces Gun for Gun et les éléments uniques du magasin Fish for Fishing. Vous pouvez voir qu'en créant les espaces, nous avons utilisé un élément de magasin pour deux choses différentes à la fois - un magasin d'armes et une poissonnerie, et nous savons exactement de quel type de magasin il s'agit grâce au fait que nous avons déclaré les espaces. Le plus intéressant commencera dans les schémas, lorsque nous pourrons ainsi valider différentes structures avec les mêmes éléments. xmlns est un attribut permettant de déclarer un espace de noms ; il peut être spécifié dans n'importe quel élément. Un exemple de déclaration d'espace de noms :
xmlns:shop= «https://barber-shop.com/»
Après les deux points se trouve un préfixe - il s'agit d'une référence d'espace qui peut ensuite être utilisée avant les éléments pour indiquer qu'ils proviennent de cet espace. La valeur xmlns doit être une CHAÎNE UNIQUE. C'est extrêmement important à comprendre : il est très courant d'utiliser des liens vers des sites Web ou des URI pour déclarer un espace de noms. Cette règle est standard car l’URI ou l’URL du lien est unique, MAIS c’est là que cela devient très déroutant. N'oubliez pas : la valeur peut être N'IMPORTE QUELLE chaîne de votre choix, mais pour être sûr qu'elle est unique et standard, vous devez utiliser une URL ou un URI. Le fait que vous puissiez utiliser n'importe quelle chaîne est illustré dans l'exemple dans Oracle :
xmlns:oracle="Unique ID #2"
xmlns:database="Unique ID #1"
Lorsque vous déclarez un espace de noms, vous pouvez l'utiliser sur l'élément lui-même et sur tous les éléments qu'il contient, de sorte que les espaces de noms déclarés sur l'élément racine peuvent être utilisés sur tous les éléments. Cela peut être vu dans le dernier exemple, et voici un exemple plus précis :
<?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>
Voici un détail important : il existe également un espace de noms standard dans l'élément racine. Si vous déclarez d'autres espaces de noms, vous remplacez celui par défaut et ne pouvez pas l'utiliser. Ensuite, vous devez mettre une sorte de préfixe d'espace devant l'élément racine, celui que vous avez déclaré précédemment. Cependant, cela peut aussi être trompé : vous pouvez déclarer explicitement l’espace standard. Il suffit simplement de ne pas utiliser de préfixe après xmlns, mais d'écrire immédiatement une valeur, et tous vos éléments sans préfixe appartiendront à cet espace de noms particulier. Le dernier exemple utilisait ceci :
<root xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.fish-shop.com/">
Nous avons déclaré explicitement l'espace standard pour éviter d'avoir à utiliser un pistolet ou un poisson, puisque l'élément racine n'est l'entité ni d'un magasin de pêche ni d'une arme, donc utiliser l'un ou l'autre espace serait logiquement incorrect. Suivant : si vous avez créé xmlns:a et xmlns:b, mais qu'ils ont la même valeur, alors il s'agit du même espace et ils ne sont pas uniques. C’est pourquoi vous devez toujours utiliser des valeurs uniques, car la violation de cette règle peut créer un grand nombre d’erreurs. Par exemple, si nous avions des espaces déclarés comme ceci :
xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.gun-shop.com/"
Notre magasin de pêche deviendrait alors un magasin d'armes, et le préfixe serait toujours une poissonnerie. Ce sont tous les points principaux des espaces. J'ai passé beaucoup de temps à les rassembler tous et à les réduire, puis à les exprimer clairement, car les informations sur les espaces sur Internet sont très énormes et souvent juste de l'eau, donc la plupart de tout ce qui est ici - je l'ai appris moi-même grâce à des essais et erreur. Si vous avez encore des questions, vous pouvez essayer de lire les documents en utilisant les liens à la fin de l'article.

Schéma XML

Je tiens à dire tout de suite que cet article ne sera que la pointe de l'iceberg, puisque le sujet est très vaste. Si vous souhaitez vous familiariser plus en détail avec les schémas et apprendre à les rédiger vous-même, quelle que soit leur complexité, il y aura à la fin de l'article un lien où tout portera sur les différents types, restrictions, extensions, etc. Je veux commencer par la théorie. Les schémas ont le format .xsd (définition de schéma XML) et constituent une alternative plus avancée et plus populaire aux DTD : ils peuvent également créer des éléments, les décrire, etc. Cependant, de nombreux bonus ont été ajoutés : vérification de type, prise en charge des espaces de noms et fonctionnalités plus larges. Vous vous souvenez lorsque nous parlions de DTD, il y avait un inconvénient : elle ne prend pas en charge les espaces ? Maintenant que nous avons étudié cela, je vais vous expliquer : s'il était possible d'importer deux ou plusieurs schémas d'une DTD, où il y a des éléments identiques, nous aurions des collisions (coïncidences) et ne pourrions pas les utiliser du tout, car on ne sait pas exactement de quel élément nous avons besoin. XSD résout ce problème car vous pouvez importer des schémas dans un espace spécifique et l'utiliser. Essentiellement, chaque schéma XSD possède un espace cible, ce qui signifie dans quel espace le schéma doit être écrit dans le fichier XML. Ainsi, dans le fichier XML lui-même, il suffit de créer ces espaces prédéfinis dans les schémas et de leur attribuer des préfixes, puis de connecter les schémas nécessaires à chacun d'eux, après quoi nous pouvons utiliser en toute sécurité des éléments du schéma, en remplaçant les préfixes de l'espace où nous avons importé les schémas. Et donc, nous avons un exemple :
<?xml version="1.0" encoding="UTF-8"?>
<house>
    <address>ул. Есенина, дом №5</address>
    <owner name="Ivan">
        <telephone>+38-094-521-77-35</telephone>
    </owner>
</house>
Nous voulons le valider avec un schéma. Tout d'abord, nous avons besoin d'un schéma :
<?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>
Comme vous pouvez le constater, les schémas sont également des fichiers XML. Vous écrivez ce dont vous avez besoin directement en XML. Ce schéma est capable de valider le fichier XML de l'exemple ci-dessus. Par exemple : si le propriétaire n'a pas de nom, le circuit le verra. De plus, grâce à l'élément séquence, l'adresse doit toujours venir en premier, puis le propriétaire de la maison. Il existe des éléments ordinaires et complexes. Les éléments réguliers sont des éléments qui stockent uniquement certains types de données. Exemple:
<element name="telephone" type="string" />
C'est ainsi que nous déclarons un élément qui stocke une chaîne. Il ne devrait y avoir aucun autre élément à l'intérieur de cet élément. Il y a aussi des éléments complexes. Les éléments complexes sont capables de stocker d’autres éléments et attributs en eux-mêmes. Ensuite, vous n'avez pas besoin de spécifier le type, mais commencez simplement à écrire un type complexe à l'intérieur de l'élément.
<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>
Il était également possible de procéder différemment : vous pouviez créer un type complexe séparément, puis le remplacer par un type. Ce n'est qu'en écrivant cet exemple que, pour une raison quelconque, il a été nécessaire de déclarer l'espace sous une sorte de préfixe et de ne pas utiliser le préfixe standard. En général, cela s'est passé comme ceci :
<?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>
De cette façon, nous pouvons créer nos propres types séparément, puis les remplacer quelque part dans l'attribut type. C'est très pratique car cela vous permet d'utiliser un type à différents endroits. Je voudrais parler davantage de la connexion des circuits et terminer ici. Il existe deux manières de connecter un circuit : dans un espace spécifique et simplement connecter.

La première façon de connecter le circuit

La première méthode suppose que le circuit possède un espace cible spécifique. Il est spécifié à l'aide de l'attribut targetNamespace sur l'élément de schéma. Il suffit ensuite de créer CE MÊME espace dans le fichier XML, puis d'y « charger » le schéma :
<?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>
Il est important de comprendre deux lignes :
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemeLocation="https://www.nedvigimost.com/ example_schema1.xsd"
La première ligne - rappelez-vous-en. Considérez-le comme un objet qui permet de charger les schémas là où ils doivent aller. La deuxième ligne est un téléchargement spécifique. schemaLocation accepte une liste de valeurs de la forme "valeur - valeur", séparées par un espace. Le premier argument est l'espace de noms, qui doit correspondre à l'espace de noms cible dans le schéma (la valeur targetNamespace). Le deuxième argument est le chemin relatif ou absolu vers le schéma. Et comme il s'agit d'une valeur LIST, vous pouvez mettre un espace après le schéma dans l'exemple, puis saisir à nouveau l'espace cible et le nom d'un autre schéma, et ainsi de suite autant que vous le souhaitez. Important:Pour que le schéma valide quelque chose ultérieurement, vous devez déclarer cet espace et l'utiliser avec un préfixe. Regardez attentivement le dernier exemple :
<?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>
Nous avons créé cet espace cible sur le préfixe nedvig puis l'avons utilisé. Ainsi, nos éléments ont commencé à être validés, puisque nous avons commencé à utiliser l'espace où est référencé l'espace du schéma cible.

La deuxième façon de connecter le circuit

La deuxième façon de connecter un circuit implique que le circuit n’ait pas d’espace cible spécifique. Ensuite vous pourrez simplement le connecter au fichier XML et il le validera. Cela se fait presque de la même manière, sauf que vous ne pouvez pas du tout déclarer d'espaces dans le fichier XML, mais simplement connecter le schéma.
<?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>
Comme vous pouvez le voir, cela se fait en utilisant noNamespaceSchemaLocation et en spécifiant le chemin d'accès au schéma. Même si le schéma ne possède pas d'espace cible, le document sera validé. Et la touche finale : nous pouvons importer d'autres diagrammes dans des diagrammes, puis utiliser des éléments d'un diagramme dans un autre. Ainsi, on peut utiliser des éléments dans certains circuits qui se trouvent déjà dans d'autres. Exemple:

Schéma où le type de propriétaire est déclaré :

<?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>

Le deuxième schéma, qui utilise le type de propriétaire du premier schéma :

<?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>
Le deuxième schéma utilise la construction suivante :
<import namespace="bonus" schemaLocation="xsd2.xsd" />
Grâce à lui, nous avons importé des types et des éléments d'un schéma à un autre dans l'espace bonus. Ainsi, nous avons accès au bonus : type propriétaire. Et dans la ligne suivante, nous l'avons utilisé :
<element name="owner" type="bonus:owner" />
Une petite attention également à la ligne suivante :
elementFormDefault="qualified"
Cet attribut est déclaré dans le schéma et signifie que dans les fichiers XML, chaque élément doit être déclaré avec un préfixe explicite devant lui. Si ce n'est pas le cas, il nous suffit alors de déclarer un élément externe avec un préfixe, et nous devons également définir des préfixes dans tous les éléments à l'intérieur, indiquant clairement que nous utilisons exactement les éléments de ce schéma. Et voici en effet un exemple de fichier XML validé par un schéma ayant importé un autre schéma :
<?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>
Dans la ligne:
<bonus:telephone>+38-094-521-77-35</bonus:telephone>
Nous devons déclarer explicitement l'espace de noms bonus, qui pointe vers l'espace cible du premier schéma, puisque elementFormDefault est qualifié (check), donc tous les éléments doivent indiquer explicitement leur espace.

Fin de l'article

Le prochain article sera le dernier de la série et portera déjà sur le traitement des fichiers XML à l'aide de Java. Nous apprendrons à obtenir des informations de différentes manières et ainsi de suite. J'espère que cet article vous a été utile et, même s'il y a des erreurs quelque part, il vous apprendra quelque chose d'utile et de nouveau, ou peut-être simplement vous donnera l'opportunité de mieux comprendre les fichiers XML. Pour ceux qui voudraient explorer cela plus en détail, j'ai décidé de rassembler un petit ensemble de liens :
  • XSD Simple Elements - à partir de cet article, commencez à lire et avancez, toutes les informations sur les schémas y sont collectées et expliquées plus ou moins clairement, uniquement en anglais. Vous pouvez utiliser un traducteur.

  • vidéo sur les espaces de noms, il est toujours utile d'écouter un autre point de vue sur quelque chose si le premier n'est pas clair.

  • Namespace XML est un bon exemple d’utilisation d’espaces de noms et est assez complet.

  • Bases de XML – Espaces de noms – Un autre court article sur les espaces de noms.

  • Les bases de l'utilisation d'un schéma XML pour définir des éléments constituent également une référence extrêmement utile sur les schémas, mais vous devez la lire lentement et attentivement, en approfondissant le contenu.

C'est tout à fait sûr, j'espère que si vous souhaitez en apprendre quelque chose de plus profond, les liens vous aideront. J'ai parcouru moi-même toutes ces sources, étudié tout le matériel et, dans l'ensemble, ce sont les plus utiles de toutes les sources que j'ai consultées, car chacune d'elles améliorait la compréhension de ce que j'avais déjà lu ailleurs, ou bien laissez-moi apprendre quelque chose de nouveau, mais beaucoup de choses ont été faites juste pendant la pratique. Donc, pour ceux qui veulent vraiment bien comprendre tout cela, mon conseil est le suivant : étudiez les espaces de noms, puis comment connecter facilement les schémas aux fichiers XML, puis comment écrire la structure du document dans des schémas. Et surtout, pratiquez. Merci à tous pour votre attention et bonne chance dans la programmation :) Article précédent : [Concours] Bases XML pour un programmeur Java - Partie 1 sur 3 Article suivant : [Concours] Bases XML pour un programmeur Java - Partie 3.1 sur 3 - SAX
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION