XML/一對多關係

維基教科書,自由的教學讀本
< XML

XML > 一對多關係


學習目標:[編輯]

完成本章內容的學習,您應該能夠

  • 在XML schema中創建自定義的數據類型
  • 在XML文檔中建立帶有屬性的空元素
  • 通過使用XML樣式表中包含有不同背景顏色、字體以及圖形顯示的表格來為一個XML文檔定義輸出形式
  • 使用解析器創建SQL插入命令

概述[編輯]

在前面的章節中,我們介紹了簡單的XML schema、XML文檔、XML樣式表以及應用於單一實體模型的簡單DOM解析器。接下

來我們將對於XML的關鍵特徵進行更多的介紹。

我們已經在前面幾章中介紹了XML schema的一些預定義的數據類型,但是,它還有許多有用的類型,例如URL、日期、時

間、年、月等。除了預定義的數據類型,schema設計者還可以根據特殊的數據輸入需要定義其他自定義的數據類型。正如我 們已經學到的,數據通過利用XML schema中定義的標記標籤在XML文檔中得到表示。但是,有一些元素可能是沒有任何取值 的。空元素標籤便是用來標記這種元素的。空元素標籤(包括其他自定義的標記標籤)可以包含屬性,這些屬性在不增加元素 額外文本的前提下記錄了該元素的附加信息。本章將會介紹在空元素標籤中使用屬性的示例。

XML樣式表允許以用戶要求的形式顯示XML文檔內容。在本章中,我們將向你展示如何使用XML樣式表中的表格來定義XML文

檔顯示格式。同時,您也將學會如何定義擁有不同背景顏色、字體大小以及文字對齊方式的顯示格式。

正如我們在前面學到的,解析器可以對XML文檔進行處理從而實現數據的轉換。我們可以利用解析器創建SQL語句,將XML文

檔數據插入數據庫。在本章中將會提供一個利用DOM解析器創建SQL插入語句的例子。

XML在歐洲中央銀行的應用[編輯]

在其他的信息中,歐洲中央銀行每天都會以XML格式發布歐元與其它貨幣的匯率。數據以如下的格式進行顯示:
<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2004-05-28">
<Cube currency="USD" rate="1.2246"/>
<Cube currency="JPY" rate="135.77"/>
<Cube currency="DKK" rate="7.4380"/>
<Cube currency="GBP" rate="0.66730"/>
<Cube currency="SEK" rate="9.1150"/>
<Cube currency="CHF" rate="1.5304"/>
<Cube currency="ISK" rate="87.72"/>
<Cube currency="NOK" rate="8.2120"/>
</Cube>
</Cube>
</gesmes:Envelope>
為了便於圖表顯示,我們在上面的代碼中省略了一些貨幣的信息。
銀行、諮詢師、匯市交易員以及涉及國際貿易的公司都是這些信息的主要使用者。

XML Schema數據類型[編輯]

在第二章中,我們介紹了一些常用的數據類型,例如字符串型、十進制型、整型和布爾型。下表中是其他一些有用的類型:

其他數據類型:

類型 格式 示例 備註
year YYYY 1999  
month YYYY-MM 1999-03 當數據元素與日期無關時使用月類型
time hh:mm:ss.sss 還有可選的時區標識 20:14:05 Z代表UTC或-hh:mm或+hh:mm來標識與UTC的差別。這種時間類型用於當你想要表示一個每天都發生的特定時間,例如4:15pm.
date YYYY-MM-DD 1999-03-14  
anyURI 域名的聲明由 http://开始 http://www.panpacific.com  
除了預定義的數據類型,我們也可以根據需求創建自定義的數據類型。自定義的數據類型可以是簡單的或是複雜的。為了簡

便起見,我們創建了一個自定義的簡單數據類型,也就是說該元素不包含其他元素或屬性,而只包含文本。為了創建一個自定 義的簡單數據類型,我們首先需要使用一個預定義的簡單類型,在應用該簡單類型時,必須附加某些約束來限制相應標籤的取 值。自定義的簡單數據類型可以被命名,也可以不被命名。如果該自定義的簡單數據類型僅使用一次,那麼對其命名便毫無意 義;這樣,這個自定義的類型只能在給出定義的位置被使用。由於被命名的類型可以重複引用(通過其名稱),這樣自定義類型可以使用在任何需要的地方。

模式可以用來精確定義元素內容的呈現方式。例如,某些情況下用戶可能會需要指定類似電話號碼、郵政編碼或產品代碼之

類的特殊格式。通過為特定元素定義模式,在轉換過程中便可以保持數據的統一性,而將相應屬性值存入數據庫中時也可以保證其與原數據的一致性。

表3-1 中的schema是對前面章節介紹過的schema的擴充,該schema通過兩個自定義數據類型,包含了city與hotel之間

的一對多關係.

1:m relationship - City Hotel

Important (newly added) lines are indicated by !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20!
21!
22!
23!
24!
25!
26!
27!
28!
29!
30!
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45!
46!
47!
48
49!
50!
51!
52!
53!
54!
55!
56!
57!
58!
59!
60!
61!
62
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified">
<!-- Tour Guide -->
<xsd:element name="tourGuide">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="city" type="cityDetails" minOccurs="1"
maxOccurs="unbounded"/> 
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- City -->
<xsd:complexType name="cityDetails">
<xsd:sequence>
<xsd:element name="cityName" type="xsd:string"/>
<xsd:element name="adminUnit" type="xsd:string"/>
<xsd:element name="country" type="xsd:string"/>
<xsd:element name="continent">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Asia"/>
<xsd:enumeration value="Africa"/>
<xsd:enumeration value="Australia"/>
<xsd:enumeration value="Europe"/>
<xsd:enumeration value="North America"/>
<xsd:enumeration value="South America"/>
<xsd:enumeration value="Antarctica"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="population" type="xsd:integer"/>
<xsd:element name="area" type="xsd:integer"/>
<xsd:element name="elevation" type="xsd:integer"/>
<xsd:element name="longitude" type="xsd:decimal"/>
<xsd:element name="latitude" type="xsd:decimal"/>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="history" type="xsd:string"/>
<xsd:element name="hotel" type="hotelDetails" minOccurs="1" 
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<!-- Hotel -->
<xsd:simpleType name="emailAddressType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\w+\W*\w*@{1}\w+\W*\w+.\w+.*\w*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="hotelDetails">
<xsd:sequence>
<xsd:element name="hotelPicture"/>
<xsd:element name="hotelName" type="xsd:string"/>
<xsd:element name="streetAddress" type="xsd:string"/>
<xsd:element name="postalCode" type="xsd:string" minOccurs="0"/>
<xsd:element name="phone" type="xsd:string"/>
<xsd:element name="emailAddress" type="emailAddressType" 
minOccurs="0"/>
<xsd:element name="websiteURL" type="xsd:anyURI" minOccurs="0"/>
<xsd:element name="hotelRating" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

表 3-1: 一對多關係的XML schema – city_hotel.xsd

讓我們仔細檢視一下上面XML:

  • {20-30}為元素「continent」定義了一個自定義的數據類型。
  • {20}<xsd:simpleType> 標記了該自定義類型定義的開始。注意,在標記中沒有定義名稱,因此該自定義數據類型是一個

無名稱的自定義簡單類型。

  • {21}<xsd:restriction base="xsd:string">,字符串xsd:是常用的預定義的簡單類型。因此,元素的取值必須是字

符串型。

    • 注意:對於自定義的類型應該定義儘可能多的約束。
  • {22-28}<xsd:enumeration>用來為元素指定一組可接受的取值,以便保持XML文檔的一致性。
    • 注意:xsd:定義了可以用於除布爾型之外的所有簡單類型的約束,而且指定的取值中可以包含空白字符。
  • {39-40}Hotel是一個定義在City中的複雜類型,其作用在於引入city與hotel之間的一對多的關係。
  • {44-48}定義了一個已命名的自定義的簡單類型(emailAddressType)。
  • {46}定義了一個特殊的模式,該模式用來定義包含有emailAddressType元素的內容可能的取值範圍。
    • 注意:正則表達式(regex)語言可以用來構建模式。XML schema中的regex語言是基於Perl的規則描述語言的。下面是

其中的一些規則:

. (the period) 任何字符
\d 任何數字t
\D 任何非數字
\w 任何單詞(或詞數混合)字符
\W 任何非單詞字符 (例如. -, +, =)
\s 任何空白 (包括空格, tab, 換行, 和回車)
\S 任何非空白字符
x* 有0個或多個x
(xy)* 有0個或多個xy
x+ 重複至少一次x
x? 有一個或0個x
(xy)? 有一個或0個xy
[abc] 包含一組取值
[0-9] 包含有從0到9的取值範圍
x{5} 一行之中有5個x
x{5,} 一行之中至少有5個x
x{5,8} 一行之中至少有5個至多有8個x
(xyz){2} 一行之中正好有2個xyz
對於例子 emailAddressType \w+\W*\w*@{1}\w+\W*\w+.\w+.*\w* 這意味着:
[w+] 至少一個單詞(或詞數混合)字符, 例如 answer
[W*] 至少一個單詞(或詞數混合)字符, 例如 -
[w*@{1}] 跟隨有任意數目(可以是0)個單詞字符 並且一個「@」 , 例如my@
[w+] 跟隨有至少一個單詞字符, 例如 mail
[W*] 跟隨有0個,1個或多個非單詞字符, 例如 _
[w+.] 至少跟隨有一個單詞字符, 例如 please.
[w+.*] 0到無限次地跟隨有前面的字符串, 例如 opentourism.
[w*] 最終跟隨有跟有0個,1個或更多單詞字符 例如 org
email地址: answer-my@mail_please.opentourism.org
  • {49-61}定義了複雜類型的簡單元素hotelDetails,目的在於定義元素的出現次序及其他信息。
  • {54,57,58}由於postalCode,emailAddress和websiteURL並不是必須出現的標準元素,因此,minOccurs="0"表明

了它們是可選的。

  • 在{44-48}中定義的自定義簡單類型emailAddressType,被用作emailAddress{56}元素的數據類型。
除了預定義的數據類型(字符串、整型等)外,為了支持特殊的輸入數據可以定

制自定義的數據類型(例如,電話號碼)。

參考第二章——實體中利用NetBeans創建XML schema的步驟創建上述schema。

XML文檔中帶屬性的空元素[編輯]

根據XML schema中的定義,元素可以擁有不同的內容類型。這些類型是元素內容、混合內容、簡單內容和空內容。XML文檔

中,在開始和結束標籤之間可以包含任何信息。

  • 擁有元素內容的為根元素——在開始和結束標籤內的任何內容都是該元素的組成成分。
例如: <tourGuide>
      :
  </tourGuide>
  • 混合內容元素是在開始和結束標籤之間擁有文本和其他元素的一類元素。
例如: <restaurant>My favorite restaurant is
  <restaurantName>Provino's Italian Restaurant</restaurantName>
      :
  </restaurant>
  • 簡單內容元素是在開始和結束標籤之間僅擁有文本的一類元素。
例如: <restaurantName>Provino's Italian Restaurant</restaurantName>
  • 空內容元素,也稱空元素,是指在開始和結束標籤中不包含任何內容(或者該元素在同一個標籤內開始並結束,通過在結束

開始標籤前加/實現)。

例如: <hotelPicture filename="pan_pacific.jpg" size="80"
          value="Image of Pan Pacific"/>
當沒有必要定義元素內容或描述該元素的信息是固定的時候便可以使用空元素。下面有兩個例子。第一,一個是通過其屬性

引用相應圖片源的圖片元素。它沒有必要定義其文本內容。第二,對於公司來說擁有者的名字是固定的,這樣便可以利用「擁 有者」標籤的屬性來定義擁有者標籤內的相關信息。屬性是元信息,即描述元素內容的信息。

屬性

  • 有效元素的命名結構同樣也適用於屬性名
  • 給定元素的所有屬性名都必須是唯一的
  • 屬性中不能包含符號「<」,可以用字符串『&lt;』來替代它。
  • 每一個屬性必須有名稱和取值。(例如,<hotelPicture filename=「pan_pacific.jpg」 />, filename是名稱而

pan_pacific.jpg 是其取值)

  • 如果取值中包含有引用的語句,引號的形式必須能夠和用來結束整個取值定義的引號區別開。(例如,如果雙引號是用來表

示整個屬性取值的,那麼在取值中則應該使用單引號來表示對於其他字符串的引用:<name familiar=」』Jack』」 >John Smith</name>)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25!
26!
27!
28!
29!
30!
31!
32!
33!
34
35
36!
37!
38!
39!
40!
41!
42!
43!
44!
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65!
66!
67!
68!
69!
70!
71!
72!
73!
74!
75!
76
77
78!
79!
80!
81!
82!
83!
84!
85!
86!
87!
88
89
90
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="city_hotel.xsl" media="screen"?>
<tourGuide xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
xsi:noNamespaceSchemaLocation=
'city_hotel.xsd' >
<city>
<cityName>Belmopa</cityName> 
<adminUnit>Cayo</adminUnit>
<country>Belize</country> 
<continent>South America</continent>
<population>11100</population>
<area>5</area> 
<elevation>130</elevation>
<longitude>12.3</longitude>
<latitude>123.4</latitude>
<description>Belmopan is the capital of Belize</description>
<history>Belmopan was established following devastation of the
former capitol, Belize City , by Hurricane Hattie in
1965. High ground and open space influenced the choice
and ground-breaking began in 1966.  By 1970 most 
government offices and operations had already moved to
the new location.
</history>
<hotel> 
<hotelPicture filename="bull_frog_inn.jpg" size="80"
value="Image of Bull Frog Inn" 
imageURL="http://www.bullfroginn.com"/>
<hotelName>Bull Frog Inn</hotelName> 
<streetAddress>25 Half Moon Avenue</streetAddress>
<phone>501-822-3425</phone>
<emailAddress>bullfrog@btl.net</emailAddress>
<websiteURL>http://www.bullfroginn.com/</websiteURL> 
<hotelRating>4</hotelRating>
</hotel>
<hotel>
<hotelPicture filename="pook_hill_lodge.jpg" size="80" 
value="Image of Pook's Hill Lodge"
imageURL="http://www.global-travel.co.uk/pook1.htm"/>
<hotelName>Pook's Hill Lodge</hotelName>
<streetAddress>Roaring River</streetAddress> 
<phone>440-126-854-1732</phone>
<emailAddress>info@global-travel.co.uk</emailAddress> 
<websiteURL>http://www.global-travel.co.uk/pook1.htm</websiteURL>
<hotelRating>3</hotelRating> 
</hotel>
</city>
<city> 
<cityName>Kuala Lumpur</cityName>
<adminUnit>Selangor</adminUnit> 
<country>Malaysia</country>
<continent>Asia</continent>
<population>1448600</population> 
<area>243</area>
<elevation>111</elevation>    
<longitude>101.71</longitude>
<latitude>3.16</latitude> 
<description>Kuala Lumpur is the capital of Malaysia and is the
largest city in the nation.</description> 
<history>The city was founded in 1857 by Chinese tin miners and
superseded Klang. In 1880 the British government transferred
their headquarters from Klang to Kuala Lumpur , and in 1896
it became the capital of Malaysia .
</history>
<hotel>
<hotelPicture filename="pan_pacific.jpg" size="80" 
value="Image of Pan Pacific"
imageURL="http://www.malaysia-hotels-discount.com/hotels/
kualalumpur/pan_pacific_hotel/index.shtml"/>
<hotelName>Pan Pacific Kuala Lumpur </hotelName>
<streetAddress>Jalan Putra</streetAddress> 
<postalCode>50746</postalCode>
<phone>1-866-260-0402</phone> 
<emailAddress>president@panpacific.com</emailAddress>
<websiteURL>http://www.panpacific.com</websiteURL> 
<hotelRating>5</hotelRating>
</hotel> 
<hotel>
<hotelPicture filename="mandarin_oriental.jpg" size="80" 
value="Image of Mandarin Oriental"
imageURL="http://www.mandarinoriental.com/kualalumpur"/> 
<hotelName>Mandarin Oriental Kuala Lumpur </hotelName>
<streetAddress>Kuala Lumpur City Centre</streetAddress> 
<postalCode>50088</postalCode>
<phone>011-603-2380-8888</phone> 
<emailAddress>mokul-sales@mohg.com</emailAddress>
<websiteURL>http://www.mandarinoriental.com/kualalumpur/</websiteURL>
<hotelRating>5</hotelRating>
</hotel> 
</city>
</tourGuide>

表 3-2: 一對多關係的XML文檔 – city_hotel.xml

讓我們檢視一下在上述XML文檔中出現的一些元素:

  • 為該XML文檔定義屏幕輸出格式的樣式表在{2}中聲明。
  • 元素「continent」的內容必須為在XML schema中為元素「continent」定義的取值集合中的一個值{10}。
  • 注意,元素hotelDetails不包含postalCode實體。但是文檔仍然是有效的,因為postalCode是可選實體。{24-45}
  • 空元素hotelPicture包含有屬性「filename」, 「size」,和「value」, 這些屬性用來記錄圖片文件的名稱以及存儲位

置、估量尺寸和關於空元素hotelPicture的描述{25,36,65,78}。

  • 元素emailAddress必須符合schema中的格式定義{32,42,73,85}。

空元素標籤中可以包含有記錄該標籤附加信息的元素屬性,同時它還無需向元素添加另外的文本。

參考第二章——單一實體中利用NetBeans創建XML文檔的步驟創建上述文檔

更多的XML樣式表特徵[編輯]

在上一章中,我們創建了一個樣式表,用來簡通過HTML頁面顯示XML文檔輸出文本。我們可以使用表格工具來規劃文檔內容

顯示所遵循的格式。另外,使用HTML中的樣式標籤還可以通過定義不同的背景顏色、字體大小以及對齊方式來完成輸出頁面 的設計。表3-3顯示了上面提到的一些屬性。注意所有的HTML命令均需大寫。

1
2
3
4
5
6
7
8
9!
10!
11!
12!
13!
14!
15!
16!
17
18
19
20!
21!
22
23
24
25
26!
27!
28!
29!
30!
31!
32!
33!
34!
35!
36!
37!
38!
39!
40!
41
42
43
44
45
46
47
48
49!
50!
51!
52!
53!
54!
55!
56!
57!
58!
59!
60!
61!
62!
63!
64!
65
66
67
68
69
70
71
72
73
74!
75!
76!
77!
78!
79!
80!
81!
82
83
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/> 
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Tour Guide</TITLE> 
<STYLE TYPE="text/css">
H2 {TEXT-ALIGN:CENTER;} 
.greenBackground {BACKGROUND-COLOR:LIGHTGREEN;
TEXT-ALIGN:CENTER;}
.yellowBackground {BACKGROUND-COLOR:YELLOW; TEXT-ALIGN:CENTER;
FONT-WEIGHT: BOLD ; FONT-SIZE:14pt;}
.salmonBackground {BACKGROUND-COLOR:LIGHTSALMON;
TEXT-ALIGN:CENTER; FONT-SIZE:12pt;}
</STYLE>
</HEAD>
<BODY> 
<H2>Cities and Hotels</H2>
<xsl:apply-templates select="tourGuide"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="tourGuide">
<TABLE BORDER="1" WIDTH="100%">
<xsl:for-each select="city">
|-----
| COLSPAN="6" CLASS="greenBackground" | <BR/>
<xsl:text>Continent: </xsl:text>
<xsl:value-of select="continent"/><BR/>
<xsl:text>Country: </xsl:text>
<xsl:value-of select="country"/><BR/>
<xsl:text>Administration Unit: </xsl:text>
<xsl:value-of select="adminUnit"/><BR/>
<xsl:text>City: </xsl:text><xsl:value-of select="cityName"/>
<BR/><BR/>
|----- CLASS="yellowBackground"
|
 || <xsl:text>Hotel Name</xsl:text> || <xsl:text>Street Address</xsl:text>
| <xsl:text>Telephone Number</xsl:text>
| <xsl:text>Email Address</xsl:text> || <xsl:text>Hotel Rating</xsl:text>
<xsl:for-each select="hotel">
|----- CLASS="salmonBackground"
| STYLE="FONT-SIZE:8pt" |
<IMG><xsl:attribute name="SRC">
<xsl:value-of select="hotelPicture/@filename"/>
</xsl:attribute>
<xsl:attribute name="WIDTH">
<xsl:value-of select="hotelPicture/@size"/>
</xsl:attribute>
<xsl:attribute name="HEIGHT">
<xsl:value-of select="hotelPicture/@size"/>
</xsl:attribute>
<xsl:attribute name="ALT">
<xsl:value-of select="hotelPicture/@value"/>
</xsl:attribute>
</IMG>
<BR/>
<xsl:value-of select="hotelPicture/@imageURL"/>
| <xsl:value-of select="hotelName"/>
| <xsl:value-of select="streetAddress"/>
| <xsl:value-of select="telephoneNumber"/>
| <xsl:value-of select="emailAddress"/>
| <xsl:value-of select="hotelRating"/>


</xsl:for-each>
|----- CLASS="salmonBackground"
| COLSPAN="6" STYLE="TEXT-ALIGN:RIGHT" |
<H3><xsl:text>Number of hotel(s) found: </xsl:text>
<xsl:value-of select="count(hotel)"/></H3>


</xsl:for-each>
</TABLE>
</xsl:template>
</xsl:stylesheet>

表3-3:用於一對多關係的XML樣式表 – city_hotel.xsl

讓我們檢視一下上述XML樣式表中需要注意的幾個地方:

  • {9-17}正如在HTML頁面中一樣,樣式標籤可以用來定義不同的顏色、字體大小、字體類型、對齊方式、邊界以及其他許多

文本格式屬性。

  • 在{21}中的xsl:apply-templates element 調用了一個在{25-82}中定義的模板,該模板定義了HTML頁面的顯示格

式。

  • {27-80}中有一個xsl:for-each元素hotel嵌套在xsl:for-each元素city中。(用來顯示表示所有城市中所有賓館的元

素hotel的適當信息)

  • {51-63}是用來顯示圖片的圖片標籤。
  • {52}在XMl schema中,圖片文件的名稱以及存儲位置被定義為空標籤hotelPicture的屬性(filename)。為了表明

filename是數據來源,圖片標籤的src屬性必須被定義。

  • {51-60}與src類似,長、寬、高這些屬性可以用來定義圖片的格式。
  • {77}<xsl:value-of select="count(hotel)"/>, count() 是一個預定義的函數,該函數的作用是計算其中參數所指

定的結點的數目。在此例子中即為賓館的數目。這表明每個城市的賓館數目已經被記錄在文檔中。

結果的輸出格式也可以使用XML樣式表中的HTML表格工具進行設計。

參考第二章——實體中關於利用NetBeans創建XML樣式表的步驟上述樣式表。

使用解析器生成SQL插入語句[編輯]

請務必在運行NetBeans程序之前設置好其中參數。可以參考第二章中設置參數和運行程序的步驟。
使用下面的代碼來對於XML文檔進行解析並且輸出SQL插入語句。
package Parser_Software;

//import class libraries needed for the parsing
//*NOTE: already included in latest Java SDK 1.4.x
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.w3c.dom.*;
import java.io.*; //import class for Input/Output
import java.util.Vector; //insert statement cache
public class MySimpleDOMParser
{
//global reference to our DOM object
static Document doc;

//parse given XML file when creating MyParser object
public MySimpleDOMParser(String filename)
{
//create file object that holds the XML file
File file = new File(filename);
try
{
/* THREE steps are needed to create a parser and save the
* document data into a DOM object
* 1. create factory object providing the parser
*/
DocumentBuilderFactory factory
= DocumentBuilderFactory.newInstance();

//2. create parser object building the DOM object
DocumentBuilder parser = factory.newDocumentBuilder();

/* 3. use parse method to create DOM object from the given file
* store the resulting DOM object into the "doc" variable
*/
doc = parser.parse(file);

/* +++NOW YOU CAN CALL ANY METHOD TO WORK WITH THIS DATA+++
* example - printNodes: prints out all nodes in the DOM tree
* - insertStatements: creates strings holding the insert
* statement If the document isn't well-formed, an exception has
* already been thrown and this has been skipped.
*/
System.out.println(file + " is well-formed.");

/* The parsing will only succeed if the XML file was well-formed,
* in anyother case it will throw an exception that is caught 
* by the following catch blocks */
}
catch (SAXException e)
{
System.out.println(file + " is not well-formed.");
}
catch (IOException e)
{
//usually happens if the file was not found
System.out.println("Due to an IOException, " +
"the parser could not check " + file);
}
catch (FactoryConfigurationError e)
{
System.out.println("Could not locate a factory class");
}
catch (ParserConfigurationException e)
{
//the JAXP class library was not loaded correctly
System.out.println("Could not locate a JAXP parser");
}
}

//create, display, and execute insert statements derived from
//the DOM object
public void insertStatements(Node n)
{
String sqlStmt;

//get the node name == table name
String tablename = n.getNodeName();

System.out.println("Creating insert statements for table: "
+ tablename);

//get a list of this nodes children
//(= holding the values to be inserted into table)
NodeList values = n.getChildNodes();

//save the information about the values that are to be
//inserted in a cache
Vector cache = new Vector();

//for every child node do the same - recursive call
for (int i = 0; i < values.getLength(); i++)
{
//browse through the children of the given node   
//(e.g. cityName, adminUnit...)
Node child = values.item(i);

//we're not interested in whitespace-text nodes, so we skip them
if (child.getNodeType() != Node.TEXT_NODE)
{
/* get the text node holding the textual information about
* the parent node e.g. "cityName" has a child text node 
* holding the city's name
*/
String insert = child.getFirstChild().getNodeValue();

//once again: skip whitespace nodes
if (insert.trim().length() != 0)
{
insert = "\""+insert+"\"";
cache.add(insert);
}
}
}//End of for-loop

sqlStmt = "INSERT INTO " + tablename + " VALUES (";
int index = 0;
while (index < cache.size()-1)
{
sqlStmt += cache.get(index) + ", ";
index++;
}
sqlStmt += cache.get(index);
System.out.print(sqlStmt);
System.out.print(");" + "\n\n");
}//End of insertStatements()

public static void main(String[] args)
{
//call this application with the command
//line arguments "file.xml file.xsd"
MySimpleDOMParser p = new MySimpleDOMParser(args[0]);

//get a list of all element nodes "city"
NodeList n = doc.getElementsByTagName("city");

//for each "city" in this node list do the following:
for (int i=0; i<n.getLength(); i++)
{ 
/* call the insertStatements method
* (which will print out the statements and //execute them)
*/
p.insertStatements(n.item(i));
}
}//End of main()

}//End of MySimpleDOMParser class

解析器輸出結果:[編輯]

c:\XML_Chapter\Chapter_3_One_to_Many\city_hotel.xml is well-formed.
Creating insert statements for table : city
INSERT INTO city VALUES ("Belmopan", "Cayo", "Belize", "South America", "11100", "5", "130", "12.3", "123.4", "Belmopan is the capital of Belize", "Belmopan was established following devastation of the
former capitol, Belize City , by Hurricane Hattie in 1965. High ground
and open space influenced the choice and ground-breaking began in
1966. By 1970 most government offices and operations had already moved
to the new location.
");
Creating insert statements for table : city
INSERT INTO city VALUES ("Kuala Lumpur", "Selangor", "Malaysia", "Asia", "1448600", "243", "111", "101.71", "3.16", "Kuala Lumpur is the capital of Malaysia and is the largest city in the nation.", "The city was founded in 1857 by Chinese tin miners and superseded
Klang. In 1880 the British government transferred their headquarters
from Klang to Kuala Lumpur , and in 1896 it became the capital of Malaysia.
");
解析器可以將XML文檔進行轉換並且將數據插入到關係數據庫中。

總結[編輯]

除了簡單的語定義數據類型(例如,年、月、時間、anyURL和日期)之外,schema的設計人員還可以根據需要創建自定義

的數據類型。簡單的自定義數據類型的創建,可以通過對預定義數據類型附加約束、定義取值集合或特定的模式來完成。

空元素不包含任何文本,但是它可以有用來記錄元素相關信息的屬性。
對於HTML頁面顯示格式的定義可以包括樣式標籤、背景顏色、字體大小、對齊方式。表格標籤可以用來組織HTML頁面中文

檔內容的輸出格式,使用了圖片標籤後,圖片也可以顯示在頁面中。

使用解析器,可以生成用來將XML文檔中數據保存在關係數據庫中的SQL插入語句。

習題[編輯]

1. 博物館通常會有不同的開館、閉館日期以及在工作日中的營業時間,同時一些博物館在周末並不開放。所以應該 創建一個存儲相關信息的日程實體來更好的記錄博物館的營業時間。

a. 創建一個描述博物館的XML schema(使用在上一章中定義的博物館實體的元素,並且在其中添加一個國家元素。定義這

些元素的可取值集合,比如國家(參見country.xsd http://www.opentoURLsm.org/xmltext/country.xsd)、日 程、開館時間、閉館時間等。並且進行良構性及有效性檢查。

b. 使用schema創建XML文檔,並且填入兩個博物館的數據,要求其中一個博物館的開放日程中包含五個不同的時間,另一

個包含七個不同的時間。並進行良構性和有效性檢查。

c. 按照如下的顯示方式編寫XML樣式表,選擇三種不同的背景顏色,2種字體,並且顯示出博物館開放日程中總計劃天數。

Insert an image of the museum – width = 80 pixels & height = 70 pixels

 

Museum Name:

Country:

 

Date

Opening Time

Closing Time

Example: 03/01/04

9:00 a.m.

7:00 p.m.

 .

 

 

Number of Calendar Days Found: __

d. 編寫一個解析XML文檔並且為日程實體生成SQL插入語句的java程序。

2. 導遊很有可能需要進行貨幣的兌換。

a. 幫助他們建立一個用來描述貨幣代碼(例如,EUR代表歐元)的良構的、有效的XML schema。匯率元素應該由3個字母

構成。在其中應該記錄有國家(例如,德國)以及相應貨幣(例如,歐元)的名稱。創建一個記錄有一部分匯率代碼的XML文 檔。(在http://www.xe.com/iso4217.htm中您將找到基於ISO4217標準http://www.opentoURLsm.org/ xmltext/curreny.xsd的所有國家貨幣的代碼。)

b. 使用Netbeans來驗證XML代碼的有效性。嘗試使用多於3個字母來描述貨幣代碼(例如,用GBxp代替GBP)。請注意利

用NetBean進行有效性檢驗時所產生的錯誤信息。

c.使用XML樣式表來生成HTML格式的輸出文件。另外在最後需要顯示不同貨幣的總數。輸出的形式應該如下圖所示:
currency code country currency name
EUR Germany Euro
... ... ...

Number of different currencies found: __

d. 登陸google並且下載表格中所列不同國家的國旗。通過使用帶屬性的空元素將它們(鏈接)包含在XML文件和HTML輸出

頁面中。