当前位置:首页 > 开发 > Web前端 > 前端 > 正文

详解XML namespace

发表于: 2012-03-13   作者:ChuanSu   来源:转载   浏览次数:
摘要: XML Namespaces 首先来看下, 为什么要引入 Namespaces 这个概念,明白了这个,我们再来一步一步挖掘 namespaces。 来看个简单的例子 <?xml version="1.0"?> <Person> <Name>Tom</Name> <Address> <
XML Namespaces

首先来看下, 为什么要引入 Namespaces 这个概念,明白了这个,我们再来一步一步挖掘 namespaces。
来看个简单的例子
<?xml version="1.0"?>
<Person>
	<Name>Tom</Name>
	<Address>
		<Street>XinHua .7</Street>
		<City>BeiJing</City>
	</Address>
</Person>

记录了一个人的基本信息,名字,家庭地址
<?xml version="1.0"?>
<Contact>
	<Address>Tom@hotmail.com</Address>
	<Tel>010-123123123</Tel>
</Contact>

记录了一个人的联系方式,电子邮箱,电话号码

可以看到,第一个xml文件存在一个 Address Element Type
第二个xml 文件同样存在一个 Address Element Type。当然如果这两个Element Type都是单独存在的话,就像上面这样,各自存在与不同的xml document当中,是完全没有问题的。

可是假如,想要对一个人做记录,其中包括名字,地址,联系方式。
<?xml version="1.0"?>
<Person>
	<Name>Tom</Name>
	<Address>
		<Street>XinHua .7</Street>
		<City>BeiJing</City>
	</Address>
	<Contact>
	    <Address>Tom@hotmail.com</Address>
	    <Tel>010-123123123</Tel>
    </Contact>
</Person>

那么程序如何分得清楚第一个Address Element Type代表的是家庭地址,而第二个则代表的是邮箱地址。不单是这个例子,假如图书馆想要对借书的人与被借走的书做个record的话,不单是Person这个Element Type 有<Name></Name>,Book同样有<Name></Name>这样的Element Type。所以这就需要引入Namespace这个重要的概念
引用
XML namespaces were originally designed to provide universally unique names for elements and attributes.
Namespace是为elements和attributs提供独一无二的Name,来避免发生上面例子当中的命名冲突。所以上面的例子可以写为
<?xml version="1.0"?>
<Person>
	<Name>Tom</Name>
	<addr:Address xmlns:addr="http//www.google.com/address">
		<addr:Street>XinHua .7</addr:Street>
		<addr:City>BeiJing</addr:City>
	</addr:Address>
	<cont:Contact xmlns:cont="http//www.google.com/contact">
	    <cont:Address>Tom@hotmail.com</cont:Address>
	    <cont:Tel>010-123123123</cont:Tel>
    </cont:Contact>
</Person>


上面知道了Namespace的作用是为elements和attribute命名的,而命名方式是 Two-Part Naming System,又叫做 expanded name即是 local name + Namespace name。 所以对与任何一个element type 和 attribute 的名字都是由 local name+ Namespace name构成的。来看下W3对local name 和 Namespace name 是怎样定义的
引用
For a name N in a namespace identified by a URI I, the namespace name is I. For a name N that is not in a namespace, the namespace name has no value.In either case the local name is N.

举个例子
<?xml version="1.0"?>
<addr:Address xmlns:addr="http://www.google.com/address">Xinhua.7</addr:Address>

对于Element type Address而言,它属于"http://www.google.com/address"这个namespace,所以它的namespace name就是"httto://www.google.com/",local name就是Address
<?xml version="1.0"?>
<Address>Xinhua.7</Address>

对于Element type Address而言, 因为没有declare任何namespace,所以它不属于任何namespace,所以它的namespace name是has no value的,但是local name仍然是 Address。

判断XML中的两个Element type 或者两个attribute是否相同时,不但要看local name是否一致,还要判断它们的namespace name 是否相同,辨别namespace name是否相同,则要看URI reference 是不是一致,URI reference 是一系列的字符即字符串,当且仅当字符串内的每一个字符都是一致的时候,才能说URI reference是相同的。
(注意,一般URL reference用普通的URL表示就可以了,这个URL只是个identifier 标识符,并不要求可以 access any resource(并不要求可以到达指定的位置)。

上面定义中分了两种情况,一种是Name N(注意每当提到XML Name的时候,都是指XML中Element type的名字或者Attribute的名字) is in a namespace,另一种是is not in a namespace。可是又怎样区分一个NAME是否属于某个namespace呢,需要先来看下 XML是怎样声明一个namespace

引用
A namespace (or more precisely, a namespace binding) is declared using a family of reserved attributes. Such an attribute's name must either be xmlns or begin xmlns:.


W3中明确说明,只有两种方式可以声明一个namespace
xmlns="......."
xmlns:NAME="......"
这两个keyword都是attribute name,统称为 NSAttName。 和
<?xml version="1.0"?>
<Person name="Tom"/>
中的属性name是一样的道理。
xmlns叫做 DefaultAttName,xmlns:NAME(此处的NAME可以是任何字符)叫做PrefixedAttName。
每当谈到一个attribute的时候,都应该想到attribute name和attribute value 例如上面的name是attribute name的名字(更准确的说,是attribute name的local name),"Tom"则是attribute value。
而对于属性 xmlns 或者 xmlns:NAME,它们的attribute value必须是URI reference或者空的字符串“”
<?xml version="1.0"?>
<Address xmlns="http://www.google.com/address"/>


<?xml version="1.0"?>
<Person xmlns:ns="http://www.google.com/person"/>

这两种方式,分别声明了名字(namespace name)为“http://www.google.com/address"的namespace 和名字为"http://www.google.com/person"的namespace。

这两种声明方式有很大的区别,区别主要在与:对Element type和attribute的作用不同,先来看 PrefixedAttName
xmlns:NAME,这个Name的作用是给namespace加了个前缀(give namespace a prefix),这个前缀是用来联系XML中的Element type 和 Attribute。例如
<?xml version="1.0"?>
<ns:Person xmlns:ns="http://www.google.com/person"/>

ns:Person,表明,Element Type Person 属于名字为“http://www.google.com/person"的namespace(Person is in this namespace) 那么对于Element type Person的namespace name 是"http://www.google.com/person/",local name是 Person.
对于下面的代码
<?xml version="1.0"?>
<Person xmlns:ns="http://www.google.com/person"/>
只能表示,声明了一个namespace,但是Element type:Person并不属于这个namespace。既然此处的person也没有被其他namespace的prefix限定,那么它的namespace name是has no value的。再重复一遍,不管这个Person属于不属于这个namespace 它的local name都是 Person。


仅仅知道如何声明namespace和如何将一个element type 或者 attribute加入到某个namespace还是不够的,还需要了解 namespace 的 scope (范围)
引用
The scope of a namespace declaration declaring a prefix extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag, excluding the scope of any inner declarations with the same NSAttName part. In the case of an empty tag, the scope is the tag itself.


意思是说,当用PrefixAttName的方式在一个Element的start-tag中声明的namespace,namespace的作用范围包括本身及所有的children,除去那些又被其他namespace 的prefix 覆盖了的element。(假如在xml文件的root element的start-tag中声明Prefix的namespace,那么这个prefix可以作用与整个xml document)
举个例子
<?xml version="1.0"?>
<addr:Address xmlns:addr="http//www.google.com/address"
	          xmlns:cont="http//www.google.com/contact">
		<addr:Street>XinHua .7</addr:Street>
		<addr:City>BeiJing</addr:City>
	    <cont:Address>Tom@hotmail.com</cont:Address>
	    <cont:Tel>010-123123123</cont:Tel>
</addr:Address>
注意可以在一个element的start-tag当中声明多个namespace,但是声明的方式必须是PrefixAttName,即xmlns:Name="....."。所声明的namespace的prefix可以不在当前的element中使用,甚至不用都可以。
可以看出 带有前缀cont的namespace是在Address的start-tag中声明的,但是前缀cont却在子元素中使用,同样,表示子元素的Element type Address与Tel 属于名字为“http://www.google.com/contact"的namespace。

再来看下 Default namespace的作用范围
所谓Default namespace 即是用DefaultAttName声明的namespace,xmlns="...."
引用

The scope of a

default namespace declaration extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag, excluding the scope of any inner default namespace declarations. In the case of an empty tag, the scope is the tag itself

对于Default namespace的声明,其作用范围和 Prefix namespace声明 是一样的,但是需要注意的是以下几点
引用
A default namespace declaration applies to all unprefixed element names within its scope. Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.

1,Default namespace的声明,在其作用范围之内,对所有的unprefixed element type(无前缀的元素)都有 默认将其添加到此namespace的作用,也就是说 如果在一个element的start-tag当中以 xmlns="...."方式声明了一个namespace,那么其当前元素及其子元素的所有的 unprefixed element type都是属于这个namespace的。
再重复一遍,既然这些unprefixed element type都属于这个namespace,那么他们的namespace name就是这个URI,local name当然还是自己了。

2,Default namespace的声明,在其作用范围之内,对所有的 unprefixed attribute是没有直接作用的,也就是说在这个作用范围之内的无前缀的attribute 并不属于这个默认的namespace,所以它们的namespace name是no value的,local name仍然是自己本身。
例如
<?xml version="1.0"?>
<Address xmlns="http//www.google.com/address">
		<Street number="7">XinHua</Street>
		<City>BeiJing</City>
</Address>

Element type Address,Street,City都是属于名字为"http://www.google.com/address"的namespace,但是 在element street中的属性number并不属于这个namespace。number的namespace name has no value,local name is number。

这时候,你肯定会想,假如我不想让其中的一个Element type属于这个默认的namespace,该怎么办。
在上面提到 对与attribute,xmlns或者xmlns:Name,他们的attribute value必须是URI或者是空字符“”,这里就用到了
<?xml version="1.0"?>
<Address xmlns="http//www.google.com/address">
		<Street number="7">XinHua</Street>
		<City xmlns="">BeiJing</City>
</Address>

可以在一个element的start-tag中声明 xmlns="",可以将此element及所有的子元素都跳出这个默认的namespace,当然对于Element type City来讲 它的namespace name是 has no value的,其local name 仍然是 City。


Qualified Name

Qualified Name 分为两种

PrefixedName(有前缀)
UnPrefixedName(无前缀)

PrefixedName 格式是 Prefix:LocalName
UnPrefixedName 格式是 LocalName
注意此处的Prefix 并不是任何形式的字符都可以,Prefix必须是bound(附于)namespace 的前缀,即xmlns:Prefix="....."

Qualified Name 有两种不同的体现形式,一是在Element Type的体现
<?xml version="1.0"?>
<bk:Book xmlns:bk="http//www.google.com/book" price="500">
		<bk:Title>I have a dream</bk:Title>
</bk:Book>

对于Element type Book,它的qualified name 是 bk:Book,
local name 是Book。
Element type Title,qualified name 是bk:Title
local name 是Title
二者的namespace name都为“http//www.google.com/book"
<?xml version="1.0"?>
<Book price="500">
		<Title>I have a dream<Title>
<Book>
此处的 Element Type Book 的 qualified name是 Book
local name 是 Book
Element Type Title 的 qualified name是 Title
local name 是 Title
二者的namespace name 都是没有值的,has no value。

Qualified Name另一种体现形式 是在 Attribute 上的体现

首先来看下XML中 Attribute的格式

1,NSAttName=Attribute Value
2,Qualified Name=Attribute Value

NSAttName,上面已经说过是xmlns与xmlns:NAME的统称。
第一种格式 主要体现在 声明namespace(Namespace declaration)上。
注意 xmlns,xmlns:NAME可以作为attribute name  但是attribute value必须是 URI reference或者Empty String (xmlns:Name=URI/xmlns="")
<?xml version="1.0"?>
<bk:Book xmlns:bk="http://www.google.com/book" bk:price="500">
		<bk:Title bk:language="English">I have a dream</bk:Title>
</bk:Book>
对于Attribute price,其qualified name 是 bk:price
local name是price
当然value 是 500
对于 Attribute language 其qualified name 是 bk:language
local name 是 language
二者的namespace name 是 “http://www.google.com/book"

最后需要注意的是 namespace name,local name,qualified name 都是针对 Element Type(Element Name) 或者 Attribute 而言的。

详解XML namespace

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
今天做了个struts2练习,发现自己对struts.xml的action配置没有理解,如下图为项目大致结构: 首先
目前做的项目,其中一个模块是由我负责,采用hibernate和spring,没有使用struts。是一个socket 服
目前做的项目,其中一个模块是由我负责,采用hibernate和spring,没有使用struts。是一个socket 服
目前做的项目,其中一个模块是由我负责,采用hibernate和spring,没有使用struts。是一个socket 服
1.struts2中action对象是什么时候创建的? 2.action类可以是一个普通的Java类,只要该Java类中包含p
转:http://www.saptechnical.com/Tutorials/XI/XMLPayload/Index.htm There are situations where a
Key Words Spring 3.0 Apache CXF 2.X.X 昨日,在原本应用中添加了关于webService的调用,使用了Apa
XML ( Extensible Markup Language ( 可拓展标记语言 )) 是SGML(标准通用标记语言)即允许用户对自己
原文: http://www.infoq.com/cn/articles/docker-kernel-knowledge-namespace-resource-isolation n
Tomcat Server的结构图 该文件描述了如何启动Tomcat Server <Server> <Listener/> <
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号