2016年11月4日 星期五

Schema 元素、子元素、命名空間

※為什麼要有schema

最主要是因為它的名稱不能重覆

※Test.dtd

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
    <!ELEMENT root (first, second)>
    <!ELEMENT first (#PCDATA)>
    <!ELEMENT second (aaa?)>
    <!ELEMENT aaa (#PCDATA)>
]>
<root>
    <first>one</first>
    <second></second>
</root>

※root下有first和second,second下有aaa,這沒有問題
但如果second下也要有first那就驗證不過,在開發中最常用到的名稱,可能有name、id、type…等,只能有一個,也未免太過份了,所以才又發明另外一種技術,Schema就出現了


※Test.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="root">
        <complexType>
            <sequence>
                <element name="first" type="string" />
                <element name="second">
                    <complexType>
                        <sequence>
                            <element name="first" type="string"/>
                        </sequence>
                    </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>

※此時second下可以有first了

※第二行可以進去看看,其實驗證還是DTD


※基本用法

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="root">
        <complexType>
            <sequence>
                <element name="first" type="string" />
                <element name="second" type="string" />
    
                <element name="third">
                    <complexType>
                        <sequence>
                            <element name="t1" type="string" />
                            <element name="t2" type="string" />
                        </sequence>
                    </complexType>
                </element>
    
                <element name="fourth" type="string" />
            </sequence>
        </complexType>
    </element>
</schema>

※裡面的語法先大概了解就好,下一篇會說明

※上面的程式碼,寫在xsd或xml都是可以的

※xmlns裡面已經定義標籤給我們用了,像element可以用,都是這裡定義好的

※基本的用法就是這樣,element的name是要產生的元素名,type是要產生的元素型態

※third裡面還有子元素



※namespace的前綴

<xxx:schema xmlns:xxx="http://www.w3.org/2001/XMLSchema">
    <xxx:element name="root">
        <xxx:complexType>
            <xxx:sequence>
                <xxx:element name="first" type="xxx:string" />
                <xxx:element name="second" type="xxx:string" />
    
                <xxx:element name="third">
                    <xxx:complexType>
                        <xxx:sequence>
                            <xxx:element name="t1" type="xxx:string" />
                            <xxx:element name="t2" type="xxx:string" />
                        </xxx:sequence>
                    </xxx:complexType>
                </xxx:element>
    
                <xxx:element name="fourth" type="xxx:string" />
            </xxx:sequence>
        </xxx:complexType>
    </xxx:element>
</xxx:schema>

※在xmlns後加上「:xxx」,xxx可以隨便打

※只要一打,全部用到這個namespace的tag也要在前面加上「xxx:」,包括schema、type

※xmlns可以有多個,前綴也可以很多,只要不重覆就行;但沒有前綴只能一個



※引用namespace

※Test.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="!@#"
    elementFormDefault="qualified">
    
    <!-- ... -->
</schema>

※…的程式碼和上面一面,只是在schema增加屬性targetNamespace,裡面可以隨便打,表示這一頁所定義的tag存在此命名空間,如first、second…等

※elementFormDefault 下一篇才會說明,這裡先固定寫qualified



※Test.xml

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="!@# ../Test2.xsd" 
    xmlns="!@#">
    
    <first>p:first</first>
    <second>p:second</second>
    <third>
        <t1>p:t1</t1>
        <t2>p:t2</t2>
    </third>
    <fourth>p:fourth</fourth>
</root>

※第一行的XMLSchema-instance不能改,表示要實作第二行 schemaLocation裡的xsd tag

※因為第一行有前綴xsi,所以第二行也要用,因為schemaLocation是這個命名空間裡的東西

※schemaLocation有兩個參數,用空格隔開
.第一個是參數是namespace名稱,從第二個參數的路徑的xsd抓到targetNamespace。
   以這個例子就是Test.xsd裡面targetNamespace的字串,兩個要一樣

.第二個參數是xsd的路徑:也可以用完整路徑,和DTD一樣,用完整路徑時,前面還要有「file:///」

※schemaLocation可以引用多個xsd,一樣用空格隔開,下面還會有範例

※xmlns表示要用哪個命名空間,雖然schemaLocation已經有tag了,但要用時,還要加上這個命名空間,裡面打上namespace的名字
因為schemaLocation可以用多個xsd,它不知道你要用哪一個



※引用多個namespace

※Test.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="123"
    elementFormDefault="qualified">
    
    <element name="root">
        <complexType>
            <sequence>
                <element name="first" type="string" />
                <element name="second" type="string" />
                <element name="third" type="string" />
            </sequence>
        </complexType>
    </element>
</schema>



※Test2.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="456"
    elementFormDefault="qualified">
    
    <element name="root">
        <complexType>
            <sequence>
                <element name="first-1" type="string" />
                <element name="second-1" type="string" />
                <element name="third-1" type="string" />
            </sequence>
        </complexType>
    </element>
</schema>

※tag和Test.xsd故意多個-1

※XXX.xml

<oooo:root xsi:schemaLocation="123 ../Test.xsd 456 ../Test2.xsd"
    xmlns:oooo="123" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <oooo:first>first</oooo:first>
    <oooo:second>second</oooo:second>
    <oooo:third>third</oooo:third>
    
    <!-- <oooo:first-1>first-1</oooo:first-1> -->
    <!-- <oooo:second-1>second-1</oooo:second-1> -->
    <!-- <oooo:third-1>thrid-1</oooo:third-1> -->
</oooo:root>

※此時使用123就要選上面那一組,456就選下面那一組



※引用no namespace

※Test.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="root">
        <complexType>
            <sequence>
                <element name="first" type="string"></element>
                <element name="second" type="string"></element>
                <element name="third" type="string"></element>
            </sequence>
        </complexType>
    </element>
</schema>

※不要寫targetNamespace



※Test.xml

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../Test.xsd">
    <first>1</first>
    <second>2</second>
    <third>3</third>
</root>

※使用noNamespaceSchemaLocation即可,裡面不能指定多個,也只能有一個noNamespaceSchemaLocation屬性

※如果Test.xsd裡有targetNamespace屬性,驗證不會過

沒有留言:

張貼留言