XML中的"xmlns"是什么意思?

497

我在一个XML文件中看到了以下行:

xmlns:android="http://schemas.android.com/apk/res/android"

我还看到许多其他的XML文件中也出现了xmlns

它是什么意思?


请看:http://programmers.stackexchange.com/questions/122002/why-do-we-need-uris-for-xml-namespaces - mcacorner
现在你也应该知道,为什么当我们不正确地使用标签或将其放置在错误的位置时,会在 XML 中出现错误。 :) - Vaibs
简而言之,xmlns有两种含义:(1) xmlns="X"表示X是默认命名空间;(2) xmlns:pf="X"表示pf是一个命名空间前缀,可以作为对X的一种缩写。请参阅下面我简明而完整的答案以了解更多详情。 - kjhughes
6个回答

806

它的意思是XML命名空间

基本上,XML中的每个元素(或属性)都属于一个命名空间,一种“限定”元素名称的方式。

想象一下,你和我都发明了自己的XML语言。 你发明了用于描述人的XML,我发明了用于描述城市的XML。 我们俩都包含了一个叫做name的元素。 你的是指人名,我的是指城市名 - 好吧,有点牵强。

<person>
    <name>Rob</name>
    <age>37</age>
    <homecity>
        <name>London</name>
        <lat>123.000</lat>
        <long>0.00</long>
    </homecity>
</person>
如果我们把这两个XML合并成一个文档,我们如何区分这两个名称?正如您在上面看到的,有两个name元素,但它们具有不同的含义。
答案是您和我都会为我们的XML分配命名空间,并使其唯一:
<personxml:person xmlns:personxml="http://www.your.example.com/xml/person"
                  xmlns:cityxml="http://www.my.example.com/xml/cities">
    <personxml:name>Rob</personxml:name>
    <personxml:age>37</personxml:age>
    <cityxml:homecity>
        <cityxml:name>London</cityxml:name>
        <cityxml:lat>123.000</cityxml:lat>
        <cityxml:long>0.00</cityxml:long>
    </cityxml:homecity>
</personxml:person>
现在我们已经全面限定了XML,对于每个name元素的含义不再有歧义。以personxml:开头的标记都属于你的XML,以cityxml:开头的标记则是我的。
需要注意以下几点:
  • 如果您排除任何命名空间声明,那么它们会被认为处于默认命名空间中。

  • 如果您声明一个没有标识符的命名空间,即xmlns="http://somenamespace"而不是xmlns:rob="somenamespace",则它指定了文档的默认命名空间。

  • 实际的命名空间本身通常是一个IRI(国际化资源标识符),它并不是非常重要。它应该是唯一的,所以人们倾向于选择自己拥有的IRI/URI,但它没有比这更大的意义。有时人们会将XML的模式(定义)放置在指定的IRI中,但这只是某些人的惯例。

  • 前缀本身并不重要,唯一重要的是前缀定义为哪个命名空间。多个以不同前缀开头的标记,所有这些前缀都映射到相同的命名空间,都被视为XML解析器中的同一个标记。

    例如,如果personxmlmycityxml两个前缀都映射到相同的命名空间(如下面的代码片段),则如果您在给定元素的前面加上personxmlmycityxml,它们都将被XML解析器视为相同的元素。重点是XML解析器不关心您选择的前缀,只关心它所映射的命名空间。前缀只是指向命名空间的一种指示方式。

<personxml:person 
     xmlns:personxml="http://example.com/same/url"
     xmlns:mycityxml="http://example.com/same/url" />
  • 属性可以被限定,但通常不会。它们也不会从它们所在的元素继承命名空间,与元素(见下文)相反。

  • 此外,元素命名空间是从父元素继承的。换句话说,我可以将以上的 XML 写成以下形式:

    <person xmlns="http://www.your.example.com/xml/person">
        <name>Rob</name>
        <age>37</age>
        <homecity xmlns="http://www.my.example.com/xml/cities">
            <name>London</name>
            <lat>123.000</lat>
            <long>0.00</long>
        </homecity>
    </person>
    

    22
    不错,这是一个有帮助的概念回答。您可能需要说明“基本上,xml中的每个元素(或属性)都属于命名空间”,因为有些元素和属性被认为是“无命名空间”。尽管我知道你在讲基础知识。 - LarsH
    1
    @Rob Levine:“属性可以命名空间,但通常不这样做。”那安卓呢? - Paweł Brewczynski
    1
    那么例如"http://www.your.example.com/xml/person"是如何使用的呢?好的,我有一个person:name标签,现在该怎么办?您也能解释一下吗? - Koray Tugay
    1
    @WORMSS - 是的 - 你说得对。当你定义查询时,需要通过前缀指定命名空间。例如,在C# System.Xml世界中,您可以使用XmlNamespaceManager.AddNamespace向命名空间管理器注册前缀,然后在查询中使用此前缀。前缀不出现在文档中并不重要 - 只有它映射到的命名空间才是重要的。 - Rob Levine
    2
    这个微软文档链接:“https://msdn.microsoft.com/zh-cn/library/aa468565.aspx”非常好地解释了XML中的命名空间。 - Deen John
    显示剩余9条评论

    323

    它定义了一个XML命名空间

    在您的示例中,命名空间前缀是“android”,命名空间URI是“http://schemas.android.com/apk/res/android

    在文档中,您可以看到像这样的元素:<android:foo />

    将命名空间前缀视为具有短名称别名的变量,以表示完整命名空间URI。 就其“含义”而言,当XML解析器读取文档时,它相当于编写<http://schemas.android.com/apk/res/android:foo />

    注意:您实际上不能在XML实例文档中使用完整的命名空间URI替换命名空间前缀。

    请查看此命名空间教程:http://www.sitepoint.com/xml-namespaces-explained/


    72
    我总是把那些URI复制到网页浏览器中,以便查看解析器正在查看什么内容,但它总是返回404错误。这个URI应该是一个需要在结尾处添加标准文件名的真实URI吗,还是只是一种生成唯一ID的技术? - Patrick
    44
    @Patrick 是的,它只是一个需要独一无二的URI,以便表示它是与其他命名空间分开的,并且任何可能的重复标记都将被正确解释。因此,该URI通常指向空内容。 - The Thirsty Ape
    4
    好的,知道它是一个命名空间很不错。我曾经想知道指定一个URI是否会使HTML页面实际访问该网站以确定模式。 - Nav
    23
    @Patrick,URI和URL不同。URL是定位器,而URI仅是标识符。您完全可以选择GUID作为URI。实际上,我们用于书籍的ISBN就是URI的一种形式。 - Jaywalker
    1
    那么标签是如何工作的?我的意思是,<LinearLayout>没有前缀也能正常工作吗? - Asif Mushtaq
    显示剩余2条评论

    24

    我认为最大的困惑在于XML命名空间指向了一个没有任何信息的URL。但事实上,发明下面这个命名空间的人:

    xmlns:android="http://schemas.android.com/apk/res/android"
    

    也可以这样称呼它:

    xmlns:android="asjkl;fhgaslifujhaslkfjhliuqwhrqwjlrknqwljk.rho;il"
    

    这只是一个唯一标识符。然而,建议您在此处放置唯一的URL,该URL可能指向该命名空间中使用的标签/属性的规范。但这不是必需的。

    为什么它应该是唯一的?因为命名空间的目的是使它们唯一,因此来自您的命名空间的例如称为background的属性可以与另一个命名空间的background区分开来。

    由于这种唯一性,您无需担心如果创建自定义属性会出现名称冲突。


    嗨,Morfidon。请问您能否在您的回答中添加一个指定该内容的参考链接或URL吗?什么是唯一的?请进一步澄清唯一性:XML命名空间的名称还是URL的内容?谢谢。 - oHo
    @olibre 如果你想使用Android的命名空间,你应该使用他们的名称。那是他们独特的名字。他们决定在那里放置一个URL。如果你正在创建自己的命名空间,那么你可以随便取名,只要确保它是唯一的。据说你应该使用指向描述该命名空间内部内容的位置的URL,但正如你所看到的,即使是Android命名空间的创建者也没有这样做。 - Morfidon
    谢谢Morfidon。在阅读Rob的回答时,我终于明白了那个点。我喜欢你的回答,因为它强调了一个重要但不太为人所知的方面。但请尝试改进你的回答,澄清哪些部分必须是独特的,提供参考资料,重新表述,检查措辞...一些读者可能会被你目前的回答所困惑。干杯! - oHo
    1
    这就是我需要的答案!对于这个属性值使用URI非常令人困惑,因为大家认为URI=URL,并且期望某个文档应该驻留在那个位置。但是据我所知,如果URI返回404,那也是完全可以的。它只是一个看起来像地址的唯一标识符。可能会有一些特殊的验证器希望在那个位置找到模式或DTD(这是有道理的),但我认为这些都是特殊情况。如果我在这里说错了,请纠正我。 - brennanyoung
    1
    @brennanyoung,正如你所说的一样 :) - Morfidon

    14

    xmlns - XML命名空间。它只是一种避免元素名称冲突的方法。例如:

    <config xmlns:rnc="URI1" xmlns:bsc="URI2">
      <rnc:node>
          <rnc:rncId>5</rnc:rncId>
      </rnc:node>
    
      <bsc:node>
          <bsc:cId>5</bsc:cId>
      </bsc:node>
    </config>
    

    在一个XML文件中有两个不同的节点元素。如果没有命名空间,这个文件将是无效的。


    4
    你可以使用命名空间来拥有全局唯一的元素。然而,在99%的情况下,这并不重要。但是,当你将其放在语义网的背景下时,它变得非常重要。
    例如,你可以通过使用适当的xmlns来混搭不同的方案,比如将好友和vCard等混搭起来。

    对于微不足道的 XML,可以忽略命名空间;但是对于其他所有情况,命名空间都是极其重要的。我真的看不出语义 Web 和命名空间之间的联系。语义 Web 是一个概念,命名空间是 XML 标准的一部分,你把接口定义和实现细节混在了一起。 - Newtopian

    0

    对一个常见问题的新、简洁而完整的回答...

    xmnls支持XML命名空间,提供了一种标准的方式来命名XML元素和属性,以便可以将独立开发的词汇表合并而不会产生命名冲突。

    XML命名空间的目的

    XML命名空间使XML模式作者能够区分在独立开发的模式中相同的元素和属性名称。基于URI的命名空间名称利用了域名的唯一性和所有权方面,以防止命名冲突(唯一性)并建立命名权威(所有权)。

    xmlns的目的

    xmlns在XML命名空间中有两种不同的用法:

    • 默认命名空间声明

      <element xmlns="http://www.example.org">
      

      声明element及其所有子元素都在http://www.example.org命名空间中默认情况下

    • 命名空间前缀声明

      <ex:element xmlns:ex="http://www.example.org">
      

      声明ex:element及其

      • 属性
      • 子元素
      • 子元素的属性

      都以ex:作为前缀,并且属于http://www.example.org命名空间。

    底线

    通过使用xmlns默认命名空间声明命名空间前缀声明,您可以安全地将您的XML与来自http://www.example.org命名空间的XML混合在一起,而不必担心命名冲突。

    另请参阅


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接