以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 DTD/XML Schema 』  (http://bbs.xml.org.cn/list.asp?boardid=23)
----  技巧: 使用模式和名称空间  (http://bbs.xml.org.cn/dispbbs.asp?boardid=23&rootid=&id=23532)


--  作者:anchen0617
--  发布时间:10/25/2005 1:04:00 PM

--  技巧: 使用模式和名称空间
随着 XML 名称空间的出现,XML 文档带有一个、两个甚至更多 XML 名称空间的现象变得很普遍。内容作者使用多个名称空间分隔内容,并且根据一组约束来验证文档的特定部分,而根据另一组约束来验证文档的另一部分。然而,随着 XML 名称空间的出现,XML Schema 规范给复杂的事物又增加了一些额外的复杂性。尽管 XML 模式允许一个更丰富的模型用于详述元素或属性的内容,但是在同一个文档内处理多个名称空间和多个模式容易出错。

CD 数据库:一个示例
在讨论细节以前,让我们研究一个简单的 XML 文档,我将用这个文档作为示例来说明这些概念。 清单 1中的文档,尽管没有多大价值,但它的确使用了两个不同的名称空间。

清单 1. 带两个名称空间的 XML

<?xml version="1.0"?>
<database xmlns="http://www.newInstance.com/cd-database"
          xmlns:sh="http://www.sugarhillrecords.com"
>
<cd title="Nickel Creek">
  <artist>Nickel Creek</artist>
  <sh:album><
   <sh:description>Bluegrass Revivalists, Acoustic Innovators,
    Youthgrass are just some of the terms that have been
    used to describe Nickel Creek over the past year -- perhaps
    producer Alison Krauss says it best:It's just Nickel Creek
    music.</sh:description>
   <sh:producer>Alison Krauss</sh:producer>
  </sh:album>
</cd>
<cd title="Ice Caps: Peaks of Telluride">
  <artist>Sam Bush</artist>
  <sh:album>
   <sh:description>Sam Bush's amazing mandolin and fiddle
    playing, singing and outrageous stage presence have
    been captivating audiences since the late 1960s. So what
    could be better-or more fun-than a live Sam Bush album
    recorded at the Telluride Bluegrass Festival, where he
    has performed for 26 years?
   </sh:description>
   <sh:producer>Sam Bush</sh:producer>
  </sh:album>
</cd>
</database>

对于任何不了解允许该文档包含什么信息的人来说,这个文档不是很有用;出于这个原因,您需要将模式分配给文档中使用的每个名称空间。尽管这里只有两个名称空间,但您可以很容易地把所介绍的这种思想推广到三个或更多的名称空间。首先,您要使用 schemaLocation 属性,用正确的名称空间来匹配每个名称空间。那还需要增加另一个名称空间; 清单 2演示了做出这两项更改后的结果。

清单 2. 用 XML 模式匹配名称空间

<?xml version="1.0"?>
<database xmlns="http://www.newInstance.com/cd-database"
          xmlns:sh="http://www.sugarhillrecords.com"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.newInstance.com/cd-database cd-database.xsd
                              http://www.sugarhillrecords.com sugarHill.xsd"
>
  <cd title="Nickel Creek">
    <artist>Nickel Creek</artist>
    <sh:album><
      <sh:description>Bluegrass Revivalists, Acoustic Innovators,
        Youthgrass are just some of the terms that have been used
        to describe Nickel Creek over the past year -- perhaps
        producer Alison Krauss says it best:It's just Nickel Creek
        music.</sh:description>
      <sh:producer>Alison Krauss</sh:producer>
    </sh:album>
  </cd>
  <cd title="Ice Caps: Peaks of Telluride">
    <artist>Sam Bush</artist>
    <sh:album>
      <sh:description>Sam Bush's amazing mandolin and fiddle playing,
        singing and outrageous stage presence have been captivating
        audiences since the late 1960s. So what could be better-or
        more fun-than a live Sam Bush album recorded at the Telluride
        Bluegrass Festival, where he has performed for 26 years?
      </sh:description>
      <sh:producer>Sam Bush</sh:producer>
    </sh:album>
  </cd>
</database>

到目前为止,一切都还不太困难。名称空间 URI 与用于该 URI 的 XML 模式结成一对,然后对下一个名称空间/模式对重复同样的事情。然而,当您开始使用 XML 模式本身时,事情就变得棘手了。

CD 数据库模式
首先,让我们从即将被引用的模式着手;该模式将用于文档的 Sugar Hill 部分,模式的名称为 sugarHill.xsd。这是最好的起点,因为它 不必引用其它模式(反过来就不正确了)。 清单 3说明了这个模式。

清单 3. Sugar Hill 模式

<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.sugarhillrecords.com"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
>
  <xs:element name="album">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="description" type="xs:string" />
        <xs:element name="producer" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

这里没有什么太奇怪的事,对吗?只是您的普通 XML 模式。然而,看看 清单 4,它演示了一个 CD 数据库模式的正在开发的版本,该模式用于 http://www.newInstance.com/cd-database名称空间。

清单 4. CD 数据库模式

<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.newInstance.com/cd-database"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
>
  <xs:element name="cd">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="artist" type="xs:string" />
        <xs:element ref="sh:album" />
      </xs:sequence>
      <xs:attribute name="title" type="xs:string" />
    </xs:complexType>
  </xs:element>
</xs:schema>

这个模式看起来没问题,但它是不完善的。尽管正确地定义了结构,但您的 XML 解析器在试图解析和计算 CD 数据库模式时会报错。那是因为它不知道如何处理 sh:album 。名称空间前缀 sh 没有被分配给名称空间 URI,而且它不知道定义 album 元素的模式在哪里。实际上,修正这个问题比您想象的要容易,接下来,我将处理这个问题。

导入模式
首先,您需要定义 Sugar Hill 名称空间 URI;这很简单,您在最初的 XML 文档中就已经这样做过了。然后,也是较难被理解的,您需要导入另一个您正在使用的 XML 模式。 清单 5 演示了 import 元素(来自 XML Schema 定义名称空间)的使用方法,以及它如何将两个 XML 模式文档链接在一起。

清单 5. CD 数据库模式

<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.newInstance.com/cd-database"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:sh="http://www.sugarhillrecords.com"
           elementFormDefault="qualified"
>
  <xs:import namespace="http://www.sugarhillrecords.com" schemaLocation="sugarHill.xsd"/>
  <xs:element name="cd">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="artist" type="xs:string" />
        <xs:element ref="sh:album" />
      </xs:sequence>
      <xs:attribute name="title" type="xs:string" />
    </xs:complexType>
  </xs:element>
</xs:schema>

增加了这两项之后,现在一切都应工作正常。您的模式现在引用 Sugar Hill 模式,并且可以解析和使用 album 元素定义。此外,您的 XML 文档已经引用了这两个模式,因此在解析文档时不会有任何问题。


--  作者:superchao
--  发布时间:3/13/2006 8:46:00 PM

--  
太好了,解决了我对名称空间的许多困惑,谢谢!
--  作者:wFirebird
--  发布时间:3/14/2006 10:10:00 AM

--  
顶一个吧~
--  作者:dendai1
--  发布时间:5/14/2006 5:56:00 PM

--  
哎!讲解得真是详细啊!-----------------对于像我这样的菜鸟来说真是太好了!
谢谢楼主!
--  作者:duckandrat
--  发布时间:7/12/2006 9:25:00 PM

--  
ding
--  作者:chenkezhong
--  发布时间:12/16/2006 9:07:00 PM

--  
看到大家好评如潮!
我怎么还没有弄明白呢!
不知所云~

--  作者:cola_cat
--  发布时间:3/7/2007 2:15:00 PM

--  
我也是看了你的帖子,突然间好像明白了!
--  作者:zhy_justin
--  发布时间:3/16/2007 4:17:00 PM

--  
写的很好,理解进一步加深了
谢谢
DING
--  作者:gaojianxun000
--  发布时间:8/29/2007 1:19:00 PM

--  
so good
--  作者:lish
--  发布时间:9/12/2007 4:09:00 PM

--  
thans very much
--  作者:melina
--  发布时间:10/23/2008 10:20:00 AM

--  
谢谢楼主哦,茅塞顿开哦
--  作者:goukili
--  发布时间:11/28/2008 2:30:00 PM

--  
我怎么觉得其中例子写错了!

xml文件中的根节点是 database,而xsd文件中只定义了 cd,因该还要添加database节点的定义阿。

如下:

    <xs:element name="database">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="cd" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="artist" type="xs:string" />
                            <xs:element ref="sh:album" />
                        </xs:sequence>
                        <xs:attribute name="title" type="xs:string" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>



W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
148.438ms