程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 在 DB2 中管理 XML Schemas,第 2 部分: XML Schemas 演變和 XML 數據管理

在 DB2 中管理 XML Schemas,第 2 部分: XML Schemas 演變和 XML 數據管理

編輯:DB2教程

簡介

對業務進行持續分析,考慮需要管理的數據種類,並相應地更新數據,是非常重要的。XML 因為靈活而很有用,但是定義數據結構並基於該結構來處理 XML 數據從而確保數據可靠性也很重要。XML schema 用於定義數據結構。

XML schema 根據業務分析結果進行更新(或演變),以下是 XML schema 演變的典型場景:

常用縮寫詞

SQL:結構化查詢語言

XML:可擴展標記語言

XSD:XML schema 定義

更新 XML schema(向上兼容性)。
XML schema 被更新,但與現有 XML schema 向上兼容。這樣,現有 XML 數據遵守新的 XML schema,無需修改 XML 數據。

更新 XML schema(不兼容)並轉換 XML 數據。
XML schema 被更新,但不與現有 XML schema 兼容。現有 XML 數據被轉換,以便適合新的 XML schema。

更新 XML schema(不兼容)並管理 XML 數據,無需數據轉換。
XML schema 被更新,但不與現有 XML schema 兼容。使用現有 XML schema 管理現有 XML 數據,無需轉換數據。

本文將解釋這些場景。

更新 XML schema(向上兼容性)

這個場景更新 XML schema,新的 schema 與現有 XML schema 向上兼容。這樣,現有 XML 數據遵守新的 XML schema,無需修改 XML 數據。

例如,本文使用以下簡單客戶信息。現有 XML schema 如 清單 1所示。遵守這個 XML schema 的 XML 數據如 清單 2所示。

清單 1. cust1.xsd(XML schema)

 <?XML version="1.0"?> 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  <xs:element name="customer"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element name="name" type="xs:string"/> 
        <xs:element name="address" type="xs:string"/> 
        <xs:element name="phone" type="xs:string"/> 
        <xs:element name="email" type="xs:string"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 
 </xs:schema> 

清單 2. cust1.XML

 <?XML version="1.0"?> 
 <customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:noNamespaceSchemaLocation="cust1.xsd"> 
  <name>cust1</name> 
  <address>address1</address> 
  <phone>11-2222-3333</phone> 
  <email>[email protected]</email> 
 </customer> 

清單 1中的 XML schema 使用以下命令注冊。要了解如何注冊 XML schema 和導入 XML 數據,參閱本系列第 1 部分 “在 DB2 中管理 XML schema,第 1 部分:管理 XML schema 並驗證 XML 數據”。

注意:這個 DB2 命令不區分大小寫,但 XML 數據和 schema 位置區分大小寫。物理位置(如 /work/customer1.xsd)是否區分大小寫取決於操作系統(Windows 不區分大小寫,但 Linux 和 UNIX 區分大小寫)。

 REGISTER XMLSCHEMA 'cust1.xsd' FROM '/work/cust1.xsd' AS SAMPLE2.CUST1; 
 COMPLETE XMLSCHEMA SAMPLE2.CUST1; 

以下命令創建表 T1 並將 清單 2中的 XML 數據導入表 T1。

 CREATE TABLE T1 (ID INT NOT NULL PRIMARY KEY, XMLDATA XML NOT NULL); 
 IMPORT FROM /work/cust1.del of del XML FROM /work 
  XMLVALIDATE USING SCHEMA SAMPLE2.CUST1 INSERT INTO T1; 

上述 IMPORT 命令中使用的 cust1.del 文件包含以下信息。值 1 在 ID 列中設置。

 1, "<XDS FIL='cust1.XML'/>" 

以下 SQL 語句用於獲取 XML schema 對象 ID、關系 ID 以及用於驗證 T1 表中每條記錄的 schema 位置。以下 SQL 語句使用一個外部聯接(outer join),以便結果中包含沒有驗證的記錄和用已經刪除的 XML schema 驗證的記錄。

 db2 => SELECT T1.ID, 
       XMLXSROBJECTID(T1.XMLDATA) OBJECTID, 
       substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA, 
       substr(XSR.OBJECTNAME,1,12) OBJECTNAME, 
       substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION 
     FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR 
     ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID; 
 
 ID     OBJECTID       OBJECTSCHEMA OBJECTNAME  SCHEMALOCATION 
 ----------- -------------------- ------------ ------------ ---------------- 
     1  65020719620281344 SAMPLE2   CUST1    cust2.xsd 
 
 1 record(s) selected. 

假定樣例 XML 中的 phone元素包含客戶的家庭電話號碼。現在向 XML 添加一個移動電話號碼。

可以定義一個新的 XML schema,與現有 XML schema 向上兼容。為此,不要修改現有元素,而是為移動電話號碼添加一個新元素(cell-phone元素),並將新添加的元素配置為可選(minOccurs="0")。參見 清單 3。

清單 3. cust2.xsd

 <?XML version="1.0"?> 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  <xs:element name="customer"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element name="name" type="xs:string"/> 
        <xs:element name="address" type="xs:string"/> 
        <xs:element name="phone" type="xs:string"/> 
        <xs:element name="cell-phone" minOccurs="0" type="xs:string"/> 
        <xs:element name="email" type="xs:string"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 
 </xs:schema> 

使用以下命令注冊 清單 3中的 XML schema。

 REGISTER XMLSCHEMA 'cust2.xsd' FROM '/work/cust2.xsd' AS SAMPLE2.CUST2; 
 COMPLETE XMLSCHEMA SAMPLE2.CUST2; 

XML schema cust2.xsd 與 XML schema cust1.xsd 向上兼容,因此 cust1.xsd 可以被 cust2.xsd 替換。

為此,發出以下 UPDATE XMLSCHEMA 命令。

 UPDATE XMLSCHEMA SAMPLE2.CUST1 WITH SAMPLE2.CUST2; 

這條命令用 cust2.xsd 替換使用關系 ID SAMPLE2.CUST1 注冊的 cust1.xsd。

清單 4是遵守新的 XML schema 的 XML 數據。

清單 4. cust2.XML

 <?XML version="1.0"?> 
 <customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:noNamespaceSchemaLocation="cust1.xsd"> 
  <name>cust2</name> 
  <address>address2</address> 
  <phone>22-3333-4444</phone> 
  <cell-phone>090-4444-5555</cell-phone> 
  <email>[email protected]</email> 
 </customer> 

在使用關系 ID 為 SAMPLE2.CUST1 的 XML schema 驗證 XML 數據後,發出以下命令在 T1 表中插入該 XML 數據。插入操作將成功執行。

 IMPORT FROM /work/cust2.del of del XML FROM /work 
  XMLVALIDATE USING SCHEMA SAMPLE2.CUST1 INSERT INTO T1; 

以上 IMPORT 命令中使用的 cust2.del 文件包含以下信息。值 2 在 ID 列中設置。

 2, "<XDS FIL='cust2.XML'/>" 

再次發出以下 SQL 語句,查看每個 XML 數據集使用哪個 XML schema 來驗證。

 db2 => SELECT T1.ID, 
       XMLXSROBJECTID(T1.XMLDATA) OBJECTID, 
       substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA, 
       substr(XSR.OBJECTNAME,1,12) OBJECTNAME, 
       substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION 
     FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR 
     ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID; 
 
 ID     OBJECTID       OBJECTSCHEMA OBJECTNAME  SCHEMALOCATION 
 ----------- -------------------- ------------ ------------ ---------------- 
     1  65020719620281344 SAMPLE2   CUST1    cust2.xsd 
     2  65020719620281344 SAMPLE2   CUST1    cust2.xsd 
 
 2 record(s) selected. 

ID 為 2 的 XML 數據使用新的 XML schema 進行驗證。上面的結果顯示,對象 ID 即使在更新了 XML schema 之後仍然沒有改變。此前驗證的 XML 數據(本例中是 ID 為 1 的 XML 數據)也遵守新的 XML schema。

關系 ID 也沒有改變,但 schema 位置更改為新的 XML schema 的位置。發出以下 SQL 語句獲取每個已注冊 XML schema 的關系 ID 和 schema 位置。

 db2 => SELECT OBJECTID, 
       substr(OBJECTSCHEMA,1,12) OBJECTSCHEMA, 
       substr(OBJECTNAME,1,12) OBJECTNAME, 
       substr(SCHEMALOCATION,1,16) SCHEMALOCATION 
     FROM SYSCAT.XSROBJECTS; 
 
 OBJECTID       OBJECTSCHEMA OBJECTNAME  SCHEMALOCATION 
 -------------------- ------------ ------------ ---------------- 
  65020719620281344 SAMPLE2   CUST1    cust2.xsd 
  66857945295662336 SAMPLE2   CUST2    cust2.xsd 
 
 2 record(s) selected. 

上面的結果顯示,兩條記錄指向相同的 schema 位置。在這種情況下,XML 數據沒有使用這個 schema 位置驗證。如下所示,使用 schema 位置 cust2.xsd 來驗證 XML 數據失敗,這是因為無法分辨使用的是哪個 schema 位置為 cust2.xsd 的 XML schema。

 db2 => INSERT INTO T1(ID, XMLDATA) VALUES (22, 
 XMLVALIDATE(XMLPARSE(DOCUMENT 
'<?XML version="1.0"?> 
 <customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:noNamespaceSchemaLocation="cust2.xsd"> 
  <name>cust2-2</name> 
  <address>address2-2</address> 
  <phone>33-4444-5555</phone> 
  <cell-phone>090-5555-6666</cell-phone> 
  <email>[email protected]</email> 
 </customer>')) 
 ); 
 DB21034E The command was processed as an SQL statement because it was not a 
 valid Command Line Processor command. During SQL processing it returned: 
 SQL16196N XML document contains an element "customer" that is not correctly 
 specifIEd. Reason code = "37" SQLSTATE=2200M 

如果按如下所示刪除其中一個 XML schema,那麼發出上述 INSERT 語句將會成功。

 DROP XSROBJECT SAMPLE2.CUST2; 

因此,使用新的 XML schema 替換現有 XML schema 後,需要將新的 XML schema 刪除掉。為此,可以在 UPDATE XMLSCHEMA 命令中使用 DROP NEW SCHEMA 選項。

 UPDATE XMLSCHEMA SAMPLE2.CUST1 WITH SAMPLE2.CUST2 DROP NEW SCHEMA; 

另一個需要考慮的問題是,schema 位置也被新的 schema 位置替換。結果,包含在現有 XML 數據中的 schema 位置不匹配。這個問題可以通過使用現有 schema 位置注冊新的 XML schema 來解決,如下所示:

 REGISTER XMLSCHEMA 'cust1.xsd' FROM '/work/cust2.xsd' AS SAMPLE2.CUST2; 
 COMPLETE XMLSCHEMA SAMPLE2.CUST2; 

然後再次使用 DROP NEW SCHEMA 選項更新 XML schema。

 UPDATE XMLSCHEMA SAMPLE2.CUST1 WITH SAMPLE2.CUST2 DROP NEW SCHEMA; 

這樣,即使在替換 XML schema 之後,驗證 XML 數據時也可以使用 schema 位置。

如果 XML schema 被更新為與現有 XML schema 具有向上兼容性,則現有 XML 數據無需任何更改就可以通過新的 XML schema 進行管理。另一方面,要保持向上兼容性,新添加的元素和屬性必須是可選的,這樣,即使您想要新添加的信息成為必要信息,也不能驗證它們是否存在。(在上面的示例中,添加了 cell-phone元素。但該元素作為可選元素添加,以便沒有 cell-phone元素的 XML 數據也可以成功通過驗證。)要了解向上兼容性的其他要求,請參閱 DB2 信息中心和 developerWorks 文章 “Evolving your XML schemas using DB2 pureXML”。

更新 XML schema(不兼容)並轉換 XML 數據

這個場景更新與現有 XML schema 不兼容的 XML schema。現有 XML 數據被轉換,以便適合新的 XML schema。

清單 5在 phone元素下面添加了 home和 cell元素,這些元素分別管理客戶的家庭電話和移動電話。它的 XML schema 如 清單 6所示。

清單 5. cust3.XML

 <?XML version="1.0"?> 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  <xs:element name="customer"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element name="name" type="xs:string"/> 
        <xs:element name="address" type="xs:string"/> 
        <xs:element name="phone" type="phoneType"/> 
        <xs:element name="email" type="xs:string"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 
  <xs:complexType name="phoneType"> 
    <xs:sequence> 
      <xs:element name="home" type="xs:string"/> 
      <xs:element name="cell" type="xs:string"/> 
    </xs:sequence> 
  </xs:complexType> 
 </xs:schema> 

清單 6. cust3.xsd

 <?XML version="1.0"?> 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  <xs:element name="customer"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element name="name" type="xs:string"/> 
        <xs:element name="address" type="xs:string"/> 
        <xs:element ref="phone"/> 
        <xs:element name="email" type="xs:string"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 
  <xs:element name="phone"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element name="home" type="xs:string"/> 
        <xs:element name="cell" type="xs:string"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 
 </xs:schema> 

XML schema 和 XML 數據(見清單 5和 6)按如下方式注冊和導入。

 REGISTER XMLSCHEMA 'cust3.xsd' FROM '/work/cust3.xsd' AS SAMPLE2.CUST3; 
 COMPLETE XMLSCHEMA SAMPLE2.CUST3; 
 IMPORT FROM /work/cust3.del of del XML FROM /work 
  XMLVALIDATE USING SCHEMA SAMPLE2.CUST3 INSERT INTO T1; 

以上 IMPORT 命令中的 cust3.del 文件包含以下信息。值 3 在 ID 列中設置。

 3, "<XDS FIL='cust3.XML'/>" 

再次發出以下 SQL 語句來獲取每個 XML 數據被哪個 XML schema 驗證。

 db2 => SELECT T1.ID, 
       XMLXSROBJECTID(T1.XMLDATA) OBJECTID, 
       substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA, 
       substr(XSR.OBJECTNAME,1,12) OBJECTNAME, 
       substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION 
     FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR 
     ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID; 
 
 ID     OBJECTID       OBJECTSCHEMA OBJECTNAME  SCHEMALOCATION 
 ----------- -------------------- ------------ ------------ ---------------- 
     1  65020719620281344 SAMPLE2   CUST1    cust1.xsd 
     2  65020719620281344 SAMPLE2   CUST1    cust1.xsd 
     22  65020719620281344 SAMPLE2   CUST1    cust1.xsd 
     3  68398419340809216 SAMPLE2   CUST3    cust3.xsd 
 
 4 record(s) selected. 

ID 為 1、2 和 22 的 XML 數據遵守 清單 3中的 XML schema cust2.xsd。(關系 ID 為 SAMPLE2.CUST1 的 XML schema 被 清單 3中的 cust2.xsd 替換,cust2.xsd 被注冊為 schema 位置 cust1.xsd。)那些 XML 數據集需要按如下方式更改以適合 cust3.xsd。

home和 cell元素需要被添加到 /customer/phone下面。

/customer/phone的值被移動到 /customer/phone/home。

如果定義了 /customer/cell-phone,那麼它被移動到 /customer/phone/cell,並且 /customer/cell-phone被刪除。

xsi:noNamespaceSchemaLocation屬性的值被更改為 cust3.xsd。(如果驗證 XML 數據時使用的是關系 ID,那麼這個步驟不是必要的。)

發出以下 SQL 語句將更改應用到 XML 數據(這個 XML 數據已經通過使用關系 ID SAMPLE2.CUST1 的 XML schema 的驗證),然後使用 schema 位置為 cust3.xsd 的 XML schema 驗證更改後的 XML 數據。

 UPDATE T1 
 SET XMLDATA=XMLVALIDATE(XMLQUERY( 
 'declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance"; 
 copy $new := $XMLDATA 
 modify ( 
  do replace $new/customer/phone with 
   <phone> 
    <home>{$new/customer/phone/text()}</home> 
    <cell>{$new/customer/cell-phone/text()}</cell> 
   </phone>, 
  do replace value of $new/customer/@xsi:noNamespaceSchemaLocation with "cust3.xsd", 
  do delete $new/customer/cell-phone ) 
 return $new')) 
 WHERE XMLXSROBJECTID(XMLDATA)=(SELECT OBJECTID FROM SYSCAT.XSROBJECTS WHERE 
 OBJECTSCHEMA='SAMPLE2' AND OBJECTNAME='CUST1') 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved