JavaRush /Java Blog /Random-TW /Java 程式設計師的 XML 基礎知識。第 2 部分(共 3 部分)
Ярослав
等級 40
Днепр

Java 程式設計師的 XML 基礎知識。第 2 部分(共 3 部分)

在 Random-TW 群組發布

介紹

你好,我的文章的親愛的讀者。這是關於 XML 的系列中的第二篇文章,本文將討論 XML 命名空間和 XML 架構。
XML 基礎知識
就在最近,我自己對此一無所知,但我已經掌握了很多材料,並將嘗試用簡單的語言解釋這兩個重要的主題。我想說,模式是一種非常先進的用於驗證 XML 文件的機制,並且比 DTD 更實用,因此這裡不會對它們進行完整的研究。讓我們開始吧 :)

XML命名空間

命名空間的意思是“名稱空間”,但在本文中,我經常將俄語表達替換為簡單的命名空間,因為它更短且更容易理解。XML命名空間是一項技術,其主要目的是確保XML檔案中的所有元素都是唯一的且不會發生混淆。由於這些是 Java 課程,因此 Java 套件中也提供了相同的技術。如果我們可以將兩個同名的類別放在一起並使用它們,我們如何確定我們需要哪個類別?這個問題可以透過套件來解決 - 我們可以簡單地將類別放在不同的套件中並從那裡導入它們,指定所需套件的確切名稱及其路徑,或者簡單地指定所需類別的完整路徑。 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 資料庫。
<?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。現在您可以在元素之前使用命名空間前綴。如果現在不清楚,也不必害怕。其實很簡單。起初,我想更快地寫出這部分文章,但在周三之後我決定需要更多地關注這個主題,因為很容易感到困惑或不理解某些東西。現在我們將重點放在 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,用於槍支商店的獨特元素和用於釣魚商店的魚的獨特元素。您可以看到,透過創建空間,我們同時將一個商店元素用於兩個不同的東西 - 武器店和魚店,並且由於我們聲明了空間,我們確切地知道它是哪種商店。最有趣的事情將從方案中開始,此時我們將能夠以這種方式驗證具有相同元素的不同結構。xmlns 是用於宣告命名空間的屬性;它可以在任何元素中指定。命名空間聲明的範例:
xmlns:shop= «https://barber-shop.com/»
冒號後面是一個前綴 - 這是一個空間引用,然後可以在元素之前使用它來指示它們來自該空間。xmlns 值必須是唯一字串。理解這一點非常重要:使用網站連結或 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 匯入兩個或多個具有相同元素的模式,我們就會發生衝突(巧合)並且根本無法使用它們,因為目前還不清楚我們需要哪個元素。XSD 解決了這個問題,因為您可以將模式匯入到一個特定空間並使用它。本質上,每個 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 檔案。例如:如果所有者沒有名字,電路就會看到這一點。此外,由於序列元素,地址應始終排在第一位,然後是房子的所有者。有普通元素和複雜元素。常規元素是僅儲存某種類型資料的元素。例子:
<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 屬性中的某個位置取代它們。這非常方便,因為它允許您在不同的地方使用一種類型。我想詳細談談連接電路,到這裡就結束了。連接電路有兩種方法:進入特定空間並直接連接。

第一種電路連接方式

第一種方法假設電路具有特定的目標空間。它是使用方案元素上的 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>
理解兩行很重要:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemeLocation="https://www.nedvigimost.com/ example_schema1.xsd"
第一行-記住它。將其視為有助於將原理圖載入到需要的位置的物件。 第二行是具體的下載。schemaLocation 接受「值 - 值」形式的值列表,以空格分隔。第一個參數是命名空間,它必須與架構中的目標命名空間(targetNamespace 值)相符。第二個參數是模式的相對或絕對路徑。由於這是一個 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 前綴上創建了這個目標空間,然後使用它。因此,我們的元素開始得到驗證,因為我們開始使用引用目標模式空間的空間。

第二種電路連接方式

連接電路的第二種方式意味著電路沒有特定的目標空間。然後您只需將其連接到 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>

第二個架構,使用第一個架構中的擁有者類型:

<?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>
第二種方案使用以下結構:
<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 基礎 - 命名空間- 另一篇關於命名空間的短文。

  • 《使用 XML 模式定義元素的基礎知識》也是一本非常有用的模式參考,但您需要慢慢地、仔細地閱讀它,深入研究其中的內容。

這是肯定的,我希望如果您想從中學到更深入的東西,這些連結會對您有所幫助。我自己瀏覽了所有這些來源,研究了所有材料,總的來說,這些是我看過的所有來源中最有用的,因為它們中的每一個要么提高了對我在其他地方已經讀過的內容的理解,要嘛讓我學到了一些新東西,但很多東西只是在練習過程中完成的。因此,對於那些真正想很好地理解這一切的人,我的建議是:研究命名空間,然後如何輕鬆地將模式連接到 XML 文件,然後如何在模式中編寫文檔結構。最重要的是,練習。感謝大家的關注,祝您編程好運 :) 上一篇文章:[競賽] Java 程式設計師的 XML 基礎知識 - 第 1 部分(共 3 部分) 下一篇文章:[競賽] Java 程式設計師的XML 基礎知識- 第3.1 部分(共3 部分)- SAX
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION