JavaRush /Java Blog /Random-JA /Java プログラマのための XML の基礎。パート 2/3
Ярослав
レベル 40
Днепр

Java プログラマのための XML の基礎。パート 2/3

Random-JA グループに公開済み

導入

私の記事を読んでいる親愛なる皆さん、こんにちは。これは XML に関するシリーズの 2 番目の記事であり、XML 名前空間と XML スキーマについて説明します。
XML の基本
私自身、つい最近までこのことについて何も知りませんでしたが、多くの内容を習得したので、これら 2 つの重要なトピックについて簡単な言葉で説明しようと思います。すぐに言っておきたいのは、スキーマは XML ドキュメントを検証するための非常に高度なメカニズムであり、DTD よりもはるかに機能的であるため、ここではスキーマの完全な研究は行いません。始めましょう :)

XML名前空間

namespace は「名前空間」を意味しますが、この記事では、ロシア語の表現を単に namespace に置き換えることがよくあります。これは、その方が短くて理解しやすいためです。XML 名前空間は、XML ファイル内のすべての要素が一意であり、混乱がないようにすることを主な目的とするテクノロジーです。これらは Java コースであるため、同じテクノロジーが Java パッケージでも利用できます。同じ名前の 2 つのクラスを並べて使用できる場合、どのクラスが必要かをどのように判断すればよいでしょうか? この問題はパッケージによって解決されます。クラスを別のパッケージに配置し、そこから目的のパッケージの正確な名前とそのパスを指定するか、目的のクラスへのフルパスを指定するだけでインポートできます。 Java プログラマのための XML の基礎。 パート 2/3 - 1これで、次のことができます。
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();
    }
}
XML 名前空間では、すべてがほとんど同じですが、少しだけ異なります。本質は同じです。要素 (クラスなど) が同じ場合、それらを異なる名前空間で使用する (パッケージを指定する) だけで済みます。要素 (クラス) の名前が一致し始めたとしても、引き続き使用できます。スペース(パッケージ)から特定の要素にアクセスします。たとえば、XML には予測 (oracle) と Oracle データベースという 2 つの要素があります。
<?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>
そして、この XML ファイルを処理するときに、データベースの代わりに予測を受け取り、またその予測も受け取った場合、私たちはひどく混乱することになります。要素の衝突を解決するために、要素を区別するためにそれぞれに独自のスペースを割り当てることができます。これには、xmlns:prefix=「名前空間の一意の値」という特別な属性があります。次に、その名前空間の一部であることを示すために要素にプレフィックスを付けることができます (基本的に、パッケージ パス、つまり名前空間を作成し、各要素にそれが属するパッケージをプレフィックスとして付ける必要があります)。
<?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>
この例では、database と oracle という 2 つの名前空間を宣言しました。要素の前に名前空間プレフィックスを使用できるようになりました。何か不明な点があったとしても、恐れる必要はありません。実際、それはとても簡単です。当初は記事のこの部分をもっと早く書きたかったのですが、混乱したり理解できなかったりしやすいため、水曜日以降にこのトピックにもっと注意を払う必要があると判断しました。ここで、xmlns 属性に注目してください。そこで、別の例を示します。
<?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>
銃ストアの固有要素にはスペースガンを使用し、釣りストアの固有要素には魚を使用した通常の XML を確認できます。スペースを作成することで、武器屋と魚屋という 2 つの異なるものに対して 1 つの店舗要素を同時に使用したことがわかります。スペースを宣言したという事実のおかげで、それがどのような種類の店舗であるかを正確に知ることができます。最も興味深いことはスキームから始まり、この方法で同じ要素を持つ異なる構造を検証できるようになります。xmlns は名前空間を宣言するための属性で、どの要素にも指定できます。名前空間宣言の例:
xmlns:shop= «https://barber-shop.com/»
コロンの後はプレフィックスです。これはスペース参照であり、要素の前に使用して、そのスペースからのものであることを示します。xmlns 値は一意の文字列である必要があります。これは理解することが非常に重要です。Web サイトのリンクまたは URI を使用して名前空間を宣言するのが非常に一般的です。リンクの URI または URL は一意であるため、このルールは標準ですが、ここが非常に混乱する場所です。覚えておいてください。値には任意の文字列を指定できますが、一意かつ標準であることを確認するには、URL または URI を使用する必要があります。任意の文字列を使用できるという事実は、Oracle の例に示されています。
xmlns:oracle="Unique ID #2"
xmlns:database="Unique ID #1"
名前空間を宣言すると、要素自体とその要素内のすべての要素で名前空間を使用できるため、ルート要素で宣言された名前空間はすべての要素で使用できます。これは最後の例で確認できますが、より具体的な例を次に示します。
<?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>
ここに重要な詳細があります。ルート要素には標準の名前空間もあります。他の名前空間を宣言すると、デフォルトの名前空間がオーバーライドされ、使用できなくなります。次に、ルート要素の前に、前に宣言した何らかのスペース接頭辞を置く必要があります。ただし、これはだまされる可能性があります。標準空間を明示的に宣言できます。xmlns の後に接頭辞を使用せず、すぐに値を書き留めるだけで十分です。接頭辞のないすべての要素は、この特定の名前空間に属します。最後の例ではこれを使用しました。
<root xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.fish-shop.com/">
ルート要素は釣具店や武器のエンティティではないため、銃や魚を使用する必要を避けるために標準スペースを明示的に宣言しました。そのため、どちらのスペースを使用しても論理的に正しくありません。次に、xmlns:a と xmlns:b を作成したが、それらの値が同じである場合、これは同じ空間であり、それらは一意ではありません。このルールに違反すると大量のエラーが発生する可能性があるため、常に一意の値を使用する必要があります。たとえば、スペースが次のように宣言されているとします。
xmlns="https://www.standart-namespace.com/" xmlns:gun="https://www.gun-shop.com/" xmlns:fish="https://www.gun-shop.com/"
そうすれば、私たちの釣具店は武器店になり、接頭語は依然として魚店になります。これらはすべてスペースの主要なポイントです。インターネット上の空間の情報は非常に膨大で、多くの場合ただの水であるため、ここにあるものはほとんどすべて私が試して学びましたそしてエラー。まだ質問がある場合は、記事の最後にあるリンクを使用して資料を読んでみてください。

XMLスキーマ

このトピックは非常に広範囲にわたるため、この記事は氷山の一角にすぎないことをすぐに言っておきたいと思います。スキームについてさらに詳しく知り、複雑なスキームを自分で記述する方法を学びたい場合は、記事の最後にリンクがあり、さまざまなタイプ、制限、拡張機能などについてすべてが説明されています。理論から始めたいと思います。スキームは .xsd (xml スキーム定義) 形式を持ち、DTD のより高度で一般的な代替手段です。スキームは要素の作成やその記述なども行うことができます。ただし、型チェック、名前空間のサポート、より幅広い機能など、多くのボーナスが追加されています。DTD について話したとき、スペースがサポートされていないというマイナス点があったことを覚えていますか? これについて学習したので、説明します。DTD から 2 つ以上のスキーマをインポートできた場合、同一の要素が存在する場合、衝突 (一致) が発生し、それらのスキーマはまったく使用できなくなります。どの要素が必要かは明確ではありません。XSD では、スキーマを 1 つの特定のスペースにインポートして使用できるため、この問題は解決されます。基本的に、すべての XSD スキーマにはターゲット スペースがあります。これは、XML ファイル内のどのスペースにスキーマを書き込むかを意味します。したがって、XML ファイル自体では、スキーマで事前定義されたこれらのスペースを作成し、それらにプレフィックスを割り当てるだけで済みます。その後、必要なスキーマをそれぞれに接続します。その後、スキーマの要素を安全に使用して、スキーマのプレフィックスを置き換えることができます。回路図をインポートしたスペース。次のような例があります。
<?xml version="1.0" encoding="UTF-8"?>
<house>
    <address>ул. Есенина, дом №5</address>
    <owner name="Ivan">
        <telephone>+38-094-521-77-35</telephone>
    </owner>
</house>
スキーマを使用して検証したいと思います。まず、スキーマが必要です。
<?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>
ご覧のとおり、スキーマも XML ファイルです。必要なものを XML で直接記述します。このスキーマは、上記の例の XML ファイルを検証できます。たとえば、所有者に名前がない場合、回路はこれを認識します。また、sequence 要素のおかげで、住所が常に最初に来て、次に家の所有者が来る必要があります。普通の要素と複雑な要素があります。通常の要素は、ある種のデータのみを格納する要素です。例:
<element name="telephone" type="string" />
これは、文字列を格納する要素を宣言する方法です。この要素内に他の要素があってはなりません。複雑な要素もあります。複合要素は、それ自体内に他の要素や属性を格納できます。その場合、型を指定する必要はなく、要素内に複合型を書き始めるだけです。
<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>
別の方法で実行することも可能でした。複合型を個別に作成し、それを type に置き換えることもできました。この例を書いているときにのみ、何らかの理由で、標準のものを使用せず、ある種の接頭辞の下でスペースを宣言する必要がありました。一般的に、次のようになりました。
<?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>
このようにして、独自の型を個別に作成し、それを type 属性のどこかに置き換えることができます。1種類で色々な場所で使えるのでとても便利です。回路の接続についてはもう少し詳しく説明して、ここで終わりにしたいと思います。回路を接続するには 2 つの方法があります。1 つは特定のスペースに接続する方法、もう 1 つは接続する方法です。

回路を接続する最初の方法

最初の方法は、回路に特定のターゲット空間があることを前提としています。これは、scheme 要素の targetNamespace 属性を使用して指定されます。次に、XML ファイル内にこれと同じスペースを作成し、そこにスキーマを「ロード」するだけで十分です。
<?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>
次の 2 つの行を理解することが重要です。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemeLocation="https://www.nedvigimost.com/ example_schema1.xsd"
最初の行を覚えておいてください。これは、必要な場所に回路図をロードするのに役立つオブジェクトと考えてください。 2 行目は特定のダウンロードです。schemaLocation は、スペースで区切られた「値 - 値」形式の値のリストを受け入れます。最初の引数はネームスペースで、スキーマ内のターゲット ネームスペース (targetNamespace 値) と一致する必要があります。2 番目の引数は、スキーマへの相対パスまたは絶対パスです。これは LIST 値であるため、例のスキームの後にスペースを入れて、ターゲット スペースや別のスキームの名前などを好きなだけ入力できます。 重要:後でスキーマで何かを検証するには、このスペースを宣言し、プレフィックスを付けて使用する必要があります。最後の例を注意深く見てください。
<?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>
このターゲット スペースを nedvig プレフィックス上に作成し、使用しました。したがって、ターゲット スキーマ空間が参照される空間を使用し始めたため、要素が検証され始めました。

回路を接続する 2 番目の方法

回路を接続する 2 番目の方法は、回路に特定のターゲット空間がないことを意味します。その後、それを XML ファイルに接続するだけで検証されます。これはほぼ同じ方法で行われますが、XML ファイル内でスペースをまったく宣言できず、単にスキーマを接続するだけです。
<?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>
ご覧のとおり、これは noNamespaceSchemaLocation を使用し、スキーマへのパスを指定して行われます。スキーマにターゲット空間がない場合でも、ドキュメントは検証されます。そして最後の仕上げとして、他の図を図にインポートし、ある図の要素を別の図で使用することができます。したがって、すでに他の回路にある要素を一部の回路で使用できます。例:

所有者の型が宣言されているスキーマ:

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

2 番目のスキーマは、最初のスキーマの所有者タイプを使用します。

<?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>
2 番目のスキームは次の構造を使用します。
<import namespace="bonus" schemaLocation="xsd2.xsd" />
これを使用して、あるスキーマから別のスキーマに型と要素をボーナス領域にインポートしました。したがって、bonus:owner タイプにアクセスできます。そして次の行ではそれを使用しました:
<element name="owner" type="bonus:owner" />
次の行にも少し注目してください。
elementFormDefault="qualified"
この属性はスキーマで宣言され、XML ファイルでは各要素の前に明示的なプレフィックスを付けて宣言する必要があることを意味します。それが存在しない場合は、接頭辞付きの外部要素を宣言するだけで済みます。また、内部のすべての要素に接頭辞を設定して、このスキームの要素を正確に使用していることを明確に示す必要があります。実際、ここに別のスキーマをインポートしたスキーマによって検証された XML ファイルの例を示します。
<?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>
行内:
<bonus:telephone>+38-094-521-77-35</bonus:telephone>
elementFormDefault が修飾 (チェック) されているため、最初のスキーマのターゲット空間を指すボーナス名前空間を明示的に宣言する必要があるため、すべての要素はその空間を明示的に示す必要があります。

記事の終わり

次の記事はシリーズの最終回であり、Java を使用した XML ファイルの処理についてすでに説明されています。さまざまな方法で情報を入手する方法などを学びます。この記事がお役に立てば幸いです。また、たとえどこかに間違いがあったとしても、役立つことや新しいことを教えてくれたり、XML ファイルをより深く理解する機会を提供できたりするかもしれません。 これをさらに詳しく調べたい人のために、小さなリンクのセットをまとめることにしました。
  • XSD シンプル要素- この記事から読み始めて先に進んでください。スキームに関するすべての情報がそこに収集されており、英語のみで多かれ少なかれ明確に説明されています。翻訳者を使用できます。

  • 名前空間に関するビデオでは、最初の視点が明確でない場合、何かについての別の視点を聞くことが常に役立ちます。

  • 名前空間 XML は名前空間の使用例の好例であり、非常に包括的です。

  • XML の基礎 - 名前空間- 名前空間に関する別の短い記事。

  • 『Basics of using XML Schema to Define Elements』もスキーマに関する非常に役立つリファレンスですが、内容を深く掘り下げてゆっくりと注意深く読む必要があります。

確かにこれだけです。ここからさらに深く学びたい場合は、リンクが役立つことを願っています。私はこれらの情報源をすべて自分で調べて、すべての資料を研究しました。全体として、これらは私が調べたすべての情報源の中で最も役に立ちました。なぜなら、それぞれの情報源は、すでにどこかで読んだ内容の理解を深めてくれたり、あるいは、何か新しいことを学ばせてもらいましたが、練習中にたくさんのことができました。したがって、これらすべてを本当によく理解したい人への私のアドバイスは、名前空間を勉強し、次にスキーマを XML ファイルに簡単に接続する方法、そしてスキーマ内にドキュメント構造を記述する方法です。そして最も重要なのは練習することです。ご清聴ありがとうございました。プログラミングの幸運を祈ります :) 前の記事: [コンテスト] Java プログラマーのための XML の基礎 - パート 1/3 次の記事: [コンテスト] Java プログラマーのための XML の基礎 - パート 3.1/3 - SAX
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION