XML 命名空间以及它们如何影响 XPath 和 XSLT (Extreme XML)

【雕爷学编程】Arduino动手做(45)---红外光电避障传感器模块4 雕爷学编程,Arduino动手做,开源硬件,创客传感器,红外光电避障传感器模块 阅读详情

XML 命名空间概述

随着 XML 在 Internet 上的使用日益广泛,能够创建可组合和重用的标记词汇表(方法类似于软件模块的组合和重用)这一优势变得日益重要。如果已经存在一个定义完善的标记词汇表,用于描述硬币集合、程序配置文件或快餐店的菜单,则重用它会比从头设计一个更有意义。将多个现有的词汇表组合在一起,以便创建“事物的整体比它各个部分的总和还大”的新词汇表,也成为 XML 用户开始需要的一个功能。

但是,在同一个文档中,来自不同词汇表的同一个标记(特别是 XML 元素和属性)可能具有不同的语义,这最终会产生问题。XML 的高度扩展性以及它在 Internet 上的广泛应用排除了只是将保留的元素或属性名称指定为此问题的解决方案。

W3C XML命名空间建议旨在创建一个机制,以便 XML 文档中来自不同标记词汇表的元素和属性可以被明确标识和组合,而无需处理所产生的问题。XML 命名空间建议提供了一种方法,以便基于处理要求对 XML 文档中的各个项目进行分区,而无需针对应当如何命名这些项目设置过多的限制。例如,名为 <template>、<output> 和 <stylesheet> 的元素可以出现在 XSLT 样式表中,而对于它们是转换指令还是转换的可能输出没有二义性。

XML 命名空间是一组由 统一资源标识符 (URI) 引用标识的名称,这些名称在 XML 文档中用作元素名称和属性名称。

命名空间声明


图 1. 利用命名空间的 XML 代码片段

命名空间声明通常用于将命名空间 URI 映射到特定的前缀。前缀-命名空间映射的作用域包括命名空间声明作用的元素及其所有的子级。前缀为 xmlns: 的属性声明是命名空间声明。类似属性声明的值应当是作为命名空间名称的命名空间 URI。

在下面的示例 XML 文档中,根元素包含一个将前缀 bk 映射到命名空间名称 urn:xmlns:25hoursaday-com:bookstore 的命名空间声明,它的子元素包含一个 inventory 元素,inventory 元素中包含一个将前缀 inv 映射到命名空间名称 urn:xmlns:25hoursaday-com:inventory-tracking 的命名空间声明。

<bk:bookstore xmlns:bk="urn:xmlns:25hoursaday-com:bookstore">
 <bk:book> 
    <bk:title>Lord of the Rings</bk:title> 
    <bk:author>J.R.R. Tolkien</bk:author>
    <inv:inventory status="in-stock" isbn="0345340426" 
        xmlns:inv="urn:xmlns:25hoursaday-com:inventory-tracking" />
 </bk:book> 
</bk:bookstore>

在上例中,urn:xmlns:25hoursaday-com:bookstore 命名空间名称的命名空间声明作用域是整个 bk:bookstore 元素,而 urn:xmlns:25hoursaday-com:inventory-tracking 的命名空间声明作用域是 inv:inventory 元素。能够识别命名空间的处理器可以独立处理来自这两个命名空间的项目,这会使其能够对 XML 文档执行多层处理。例如,RDDL 文档是有效的 XHTML 文档,这些文档不仅可以由 Web 浏览器呈现,而且还包含使用 http://www.rddl.org 命名空间中元素的信息,该命名空间可用于查找有关 XML 命名空间成员的机读资源。

应当注意的是,按照定义,前缀 xml 绑定到 XML 命名空间名称,而且这个特殊的命名空间自动在每个格式规范的 XML 文档中对文档作用域预先进行声明。

默认命名空间

有关命名空间声明的上一节不是完整的,因为它未考虑默认命名空间。默认命名空间声明是一个属性声明,该属性声明的名称是 xmlns,其值是作为命名空间名称的命名空间 URI。

默认命名空间声明指定其作用域中所有不带前缀的元素名称都来自声明的命名空间。下面的书店示例使用默认命名空间,而不使用前缀-命名空间映射。

<bookstore xmlns="urn:xmlns:25hoursaday-com:bookstore">
 <book> 
    <title>Lord of the Rings</title> 
    <author>J.R.R. Tolkien</author>
    <inv:inventory status="in-stock" isbn="0345340426" 
        xmlns:inv="urn:xmlns:25hoursaday-com:inventory-tracking" />
 </book> 
</bookstore>

在上例中,除 inv:inventory 元素以外的所有元素都属于 urn:xmlns:25hoursaday-com:bookstore 命名空间。默认命名空间的主要目的是缩短使用命名空间的 XML 文档。但是,如果对于元素名称使用默认命名空间,而不使用显式映射的前缀,可能会导致混淆,因为文档中的元素不是明显地属于命名空间的作用域。

此外,与常规的命名空间声明不同的是,默认命名空间声明可以通过将 xmlns 属性的值设置为空字符串来取消声明。应当避免取消对默认命名空间声明的声明,因为这一做法可能导致在文档的一部分中,具有属于某个命名空间且不带前缀的名称,但是在另一部分中却没有。例如,在下面的文档中,只有 bookstore 元素来自 urn:xmlns:25hoursaday-com:bookstore,而其他不带前缀的元素没有命名空间名称。

<bookstore xmlns="urn:xmlns:25hoursaday-com:bookstore">
 <book xmlns=""> 
    <title>Lord of the Rings</title> 
    <author>J.R.R. Tolkien</author>
    <inv:inventory status="in-stock" isbn="0345340426" 
        xmlns:inv="urn:xmlns:25hoursaday-com:inventory-tracking" />
 </book> 
</bookstore>

应当避免这一做法,因为它对于 XML 文档的读者会产生非常容易混淆的情况。有关对命名空间声明取消声明的详细信息,请参阅“命名空间的未来”一节。

限定名称和扩展名称

限定名称又称为 QName,是一个名为本地名称的 XML 名称,它的前面可以有另一个名为前缀的 XML 名称和一个冒号 (':')字符。用作前缀的 XML 名称和本地名称必须与产生的 NCName 相匹配,这意味着它们不得包含冒号字符。限定名称的前缀必须已经通过作用域内的命名空间声明(将前缀映射到命名空间 URI)映射到命名空间 URI。限定名称可以用作属性名称,也可以用作元素名称。

尽管 QName 是重要的助记指导,可以帮助确定文档中的元素和属性是从哪个命名空间派生的,但是它们对于能够识别 XML 的处理器无关紧要。例如,下面的三个 XML 文档将被一系列 XML 技术(当然包括 XML 架构验证程序)以同样的方式处理。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:complexType id="123" name="fooType"/>
</xs:schema>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:complexType id="123" name="fooType"/>
</xsd:schema>

<schema xmlns="http://www.w3.org/2001/XMLSchema">
        <complexType id="123" name="fooType"/>
</schema>

W3C XML 路径语言建议将扩展名称描述为命名空间名称和本地名称对。通用名称是由 James Clark 创造的一个替换术语,可用来描述同一个概念。通用名称由命名空间名称(用大括号括起来)和本地名称组成。从通用名称的角度看,命名空间对于人们的意义更大。下面是上面示例中的三个 XML 文档,但是 QName 被替换为通用名称。请注意,下面的语法不是有效的 XML 语法。

<{http://www.w3.org/2001/XMLSchema}schema>  
<{http://www.w3.org/2001/XMLSchema}complexType id="123" name="fooType"/>
</{http://www.w3.org/2001/XMLSchema}schema>

<{http://www.w3.org/2001/XMLSchema}schema>  
<{http://www.w3.org/2001/XMLSchema}complexType id="123" name="fooType"/>
</{http://www.w3.org/2001/XMLSchema}schema>

<{http://www.w3.org/2001/XMLSchema}schema>  
<{http://www.w3.org/2001/XMLSchema}complexType id="123" name="fooType"/>
</{http://www.w3.org/2001/XMLSchema}schema>

对许多 XML 应用程序来说,XML 文档中元素和属性的通用名称非常重要,而用在特定 QName 中的前缀的值并不重要。XML 中的命名空间建议之所以没有使用扩展名称方法来指定命名空间,主要是因为它很冗长。相反,之所以提供前缀映射和默认命名空间,是为了避免我们因不断键入命名空间 URI 而产生腕管综合症。

命名空间和属性

除非属性的名称有前缀,否则命名空间声明不应用于属性。在下面显示的 XML 文档中,title 属性属于 bk:book 元素且没有命名空间,而 bk:title 属性将 urn:xmlns:25hoursaday-com:bookstore 作为其命名空间名称。请注意,即使这两个属性具有相同的本地名称,该文档的结构也是完整的。

<bk:bookstore xmlns:bk="urn:xmlns:25hoursaday-com:bookstore">
   <bk:book title="Lord of the Rings, Book 3" bk:title="Return of the King"/> 
</bk:bookstore> 

在下例中,即使指定了一个默认命名空间,title 属性仍然没有命名空间,且属于 book 元素。换句话说,属性不能继承默认命名空间。

<bookstore xmlns="urn:xmlns:25hoursaday-com:bookstore">
   <book title="Lord of the Rings, Book 3" /> 
</bookstore> 

命名空间 URI

按照 RFC 2396 中的规定,命名空间名称是统一资源标识符 (URI)。URI 是统一资源定位器 (URL) 或统一资源名称 (URN)。URL 用于指定资源在 Internet 上的位置,而 URN 应该是信息资源持久的、独立于位置的标识符。对于不同的命名空间名称来说,只有当它们的每个字符(区分大小写)都相同时,才被视为相同。之所以将 URI 用作命名空间名称,主要是因为它们已经提供了一种用来指定全局唯一标识符的机制。

XML 命名空间建议声明,命名空间名称只是充当唯一标识符,而不必实际标识可从网络检索的资源。这就在 XML 文档的作者和用户之间产生了很大的混淆,特别是由于人们已经普遍将基于 HTTP 的 URL 用作命名空间名称。因为许多应用程序都将这样的 URI 转换为超级链接,但是当这些“链接”无法跳转到网页或其他可从网络检索的资源时,会令许多用户感到恼火。我记得有一个用户将这比作在社交场合中得到了一个假电话号码。

为了避免使用户感到混淆,一个解决方案就是使用不暗示资源具有网络可检索性的命名空间-命名架构。在编写供个人使用的 XML 文档时,我使用 urn:xmlns: 方案来实现此目的,并创建了一个类似于 urn:xmlns:25hoursaday-com 的命名空间名称。自建命名空间 URI 有一个问题,那就是它们可能会由于全局不唯一而与 XML 中的名称建议相抵触。我通过将我的个人域名 http://www.25hoursaday.com 用作命名空间 URI 的一部分来满足这个全局唯一要求。

另一个解决方案是将可从网络检索的资源保留在作为命名空间名称的 URI(如用 XSLT 和 RDDL 命名空间实现的 URI)处。通常,这样的 URI 实际上是 HTTP URL。通过使用 W3C 所建议的格式,可以很好地对这样的 URL 进行命名,如下所示:

      http://my.domain.example.org/product/[year/month][/area]

有关将结构类似的命名空间名称用作版本控制机制的详细信息,请参阅“命名空间和版本控制”一节。

有关命名空间的 DOM、XPath 和 XML 信息集

W3C 已经定义了许多可以为 XML 文档提供数据模型的技术。这些数据模型通常是一致的,但是由于历史原因,它们在处理各种边缘案例的方式上有时会有所不同。对 XML 命名空间和命名空间声明的处理就是边缘案例的一个示例,在 W3C 建议中的三个主要数据模型中,该案例会以不同的方式进行处理。这三个数据模型是 XPath 数据模型、文档对象模型 (DOM) 和 XML 信息集。

XML 信息集 (XML infoset) 是对 XML 文档中数据的抽象说明,它可视为 XML 文档的主要数据模型。XPath 数据模型是类似于 XML 信息集的基于树的模型,在查询 XML 文档时会遍历该模型。DOM 优先于 XPath 和 XML 信息集这两种数据模型,但是它在许多方面也与这两个数据模型相似。DOM 和 XPath 数据模型可视为对 XML信息集的解释。

文档对象模型 (DOM) 中的命名空间

DOM Level 3 规范的 XML 命名空间部分将命名空间声明视为以 http://www.w3.org/2000/xmlns/ 作为其命名空间名称的常规属性节点,并将 xmlns 视为它们的前缀或限定名称。

DOM 中的元素和属性有一个无法在创建之后进行修改的命名空间名称,不管它们在文档中的位置是否发生改变。

XPath 数据模型中的命名空间

W3C XPath 建议不将命名空间声明视为属性节点,而且不提供以该资格访问它们的权限。相反,在 XPath 中,XML 文档中的每个元素都有许多可使用 XPath 命名空间导航轴检索的命名空间节点。

在文档中每个元素的作用域内,该元素对于每个命名空间声明都有一组唯一的命名空间节点。在该命名空间中,命名空间节点对于每个元素都是唯一的。因此,代表同一个命名空间声明的两个不同元素的命名空间节点是不同的。

XML 信息集中的命名空间

XML 信息集建议将命名空间声明视为属性信息项。

另外,与 XPath 数据模型相似的是,XML 文档信息集内的每个元素信息项,对于该元素作用域内每个命名空间都有一个命名空间信息项目。

 

XPath、XSLT 和命名空间

W3C XML 路径语言(也称为 XPath)用于对 XML 文档的某些部分进行寻址,它可用在许多 W3C XML 技术(包括 XSLT、XPointer、XML 架构和 DOM Level 3)中。XPath 使用类似于文件系统和 URL 中使用的分层寻址机制来检索 XML 文档的某些部分。XPath 支持对字符串、数字和布尔值进行基本操作。

XPath 和命名空间

XPath 数据模型将 XML 文档视为节点(如元素、属性和文本节点)树。在节点树中,每个节点的名称都由其本地名称和命名空间名称(即,它的通用名称或扩展名称)组合而成。

对于没有命名空间的元素和属性节点,执行 XPath 查询是相当简单的。下面的程序可用于从命令行查询 XML 文档,并将用来阐释命名空间对 XPath 查询的影响。

using System.Xml.XPath; 
using System.Xml; 
using System;
using System.IO; 

class XPathQuery{

public static string PrintError(Exception e, string errStr){

  if(e == null) 
    return errStr; 
  else
    return PrintError(e.InnerException, errStr + e.Message ); 
} 

 public static void Main(string[] args){

   if((args.Length == 0) || (args.Length % 2)!= 0){
     Console.WriteLine("Usage: xpathquery source query <zero or more 
prefix and namespace pairs>");
      return; 
   }
   
   try{
     
     //Load the file.
     XmlDocument doc = new XmlDocument(); 
     doc.Load(args[0]); 

     //create prefix<->namespace mappings (if any) 
     XmlNamespaceManager  nsMgr = new XmlNamespaceManager(doc.NameTable);

     for(int i=2; i < args.Length; i+= 2)
       nsMgr.AddNamespace(args[i], args[i + 1]); 

     //Query the document 
     XmlNodeList nodes = doc.SelectNodes(args[1], nsMgr); 

     //print output 
     foreach(XmlNode node in nodes)
       Console.WriteLine(node.OuterXml + "/n/n");

   }catch(XmlException xmle){
     Console.WriteLine("ERROR: XML Parse error occured because " + 
PrintError(xmle, null));
   }catch(FileNotFoundException fnfe){
     Console.WriteLine("ERROR: " + PrintError(fnfe, null));
   }catch(XPathException xpath){
     Console.WriteLine("ERROR: The following error occured while querying 
the document: " 
             + PrintError(xpath, null));
   }catch(Exception e){
     Console.WriteLine("UNEXPECTED ERROR" + PrintError(e, null));
   }
 }
}

假设下面的 XML 文档不声明任何命名空间,则查询相当简单,如以下代码后面的示例所示。

<?xml version="1.0" encoding="utf-8" ?> 
<bookstore> 
  <book genre="autobiography">
    <title>The Autobiography of Benjamin Franklin</title>
    <author>
      <first-name>Benjamin</first-name>
      <last-name>Franklin</last-name>
    </author>
    <price>8.99</price>
  </book>
  <book genre="novel">
    <title>The Confidence Man</title>
    <author>
      <first-name>Herman</first-name>
      <last-name>Melville</last-name>
    </author>
    <price>11.99</price>
  </book>
</bookstore>

示例 1

•
xpathquery.exe bookstore.xml /bookstore/book/title 

选择所有作为 book 元素(其父级为 bookstore 元素)子级的标题元素,并返回如下结果:

   <title>The Autobiography of Benjamin Franklin</title>
   <title>The Confidence Man</title>
•
xpathquery.exe bookstore.xml //@genre 

选择文档中的所有 genre 属性并返回如下结果:

   genre="autobiography"
   genre="novel"
•
xpathquery.exe bookstore.xml //title[(../author/first-name = 'Herman')] 

选择作者名为 "Herman" 的所有标题并返回如下结果:

   <title>The Confidence Man</title>  

但是,在将命名空间添加到混合名称中之后,事情不再那么简单。除了向某个 book 元素中添加了命名空间和一个属性以外,下面的文件与原始文件相同。

<bookstore xmlns="urn:xmlns:25hoursaday-com:bookstore">
  <book genre="autobiography">
    <title>The Autobiography of Benjamin Franklin</title>
    <author>
      <first-name>Benjamin</first-name>
      <last-name>Franklin</last-name>
    </author>
    <price>8.99</price>
  </book>
  <bk:book genre="novel" bk:genre="fiction" 
xmlns:bk="urn:xmlns:25hoursaday-com:bookstore">
    <bk:title>The Confidence Man</bk:title>
    <bk:author>
      <bk:first-name>Herman</bk:first-name>
      <bk:last-name>Melville</bk:last-name>
    </bk:author>
    <bk:price>11.99</bk:price>
  </bk:book>
</bookstore>

请注意,默认命名空间位于整个 XML 文档的作用域内,而将前缀 bk 映射到命名空间名称 urn:xmlns:25hoursaday-com:bookstore 的命名空间声明只位于第二个 book 元素的作用域内。

示例 2

•
xpathquery.exe bookstore.xml /bookstore/book/title 

选择所有作为 book 元素(其父级为 bookstore 元素)子级的标题元素,这不返回任何结果。

•
xpathquery.exe bookstore.xml //@genre 

选择文档中的所有 genre 属性并返回如下结果:

   genre="autobiography"
   genre="novel"
•
xpathquery.exe bookstore.xml //title[(../author/first-name = 'Herman')] 

选择作者名字为 "Herman" 的所有标题,这不返回任何结果。

第一个查询之所以不返回任何结果,是因为 XPath 查询中不带前缀的名称应用于没有命名空间的元素或属性。在没有命名空间的目标文档中没有 bookstore、book 或 title 元素。第二个查询返回没有命名空间的所有属性节点。尽管命名空间声明位于由该查询返回的这两个属性节点的作用域内,但是由于命名空间声明不应用于没有前缀名称的属性,所以它们没有命名空间。出于与第一个查询同样的原因,第三个查询不返回任何结果。

可通过以下方法来执行能够识别命名空间的 XPath 查询:提供一个到 XPath 引擎的前缀-命名空间映射,然后在该查询中使用这些前缀。所提供的前缀不必与目标文档中的命名空间-前缀映射相同,而且它们必须是非空前缀。

示例 3

•
xpathquery.exe bookstore.xml /b:bookstore/b:book/b:title b urn:xmlns:25hoursaday-com:bookstore 

选择所有作为 book 元素(其父级为 bookstore 元素)子级的标题元素,并返回如下结果:

    <title xmlns="urn:xmlns:25hoursaday-com:bookstore">The Autobiography of Benjamin Franklin</title>
   <bk:title xmlns:bk="urn:xmlns:25hoursaday-com:bookstore">The Confidence Man</bk:title>
•
xpathquery.exe bookstore.xml //@b:genre b urn:xmlns:25hoursaday-com:bookstore

选择文档中来自 "urn:xmlns:25hoursaday-com:bookstore" 命名空间的所有 genre 属性并返回如下结果:

   bk:genre="fiction"
•
xpathquery.exe bookstore.xml //bk:title[(../bk:author/bk:first-name = 'Herman')] bk urn:xmlns:25hoursaday-com:bookstore 

选择作者名为 "Herman" 的所有标题并返回如下结果:

   <bk:title xmlns:bk="urn:xmlns:25hoursaday-com:bookstore">The Confidence Man</bk:title>

注意 示例 3 与示例 1 和 2 相同,但是它被重写为能够识别命名空间。

有关使用 XPath 的详细信息,请阅读 Aaron Skonnard 的文章 Addressing Infosets with XPath 并查看 ZVON.org XPath tutorial 上的示例。

XSLT 和命名空间

W3C XSL 转换 (XSLT) 建议描述一种基于 XML 的语言,用于将 XML 文档转换为其他 XML 文档。XSLT 转换又称为 XML 样式表,它使用模式 (XPath) 来与目标文档的各个方面进行匹配。在与目标文档中的节点进行匹配时,可以对那些指定成功匹配输出结果的模板进行实例化,并使用这些模板来转换文档。

对命名空间的支持已紧密集成到 XSLT 中,特别是由于 XPath 用于与源文档中的节点进行匹配。在 XSLT 内部的 XPath 表达式中使用命名空间比使用 DOM 方便得多。

随后的示例包含:

•

一个用于从命令行执行转换的程序。

•

一个 XSLT 样式表,当它在来自 urn:xmlns:25hoursaday-com:bookstore 命名空间的 bookstore 文档中运行时,打印源 XML 文档中来自 urn:xmlns:25hoursaday-com:bookstore 的所有 title 元素。

•

得到的输出结果。

程序

Imports System.Xml.Xsl
Imports System.Xml
Imports System
Imports System.IO

Class Transformer

   Public Shared Function PrintError(e As Exception, errStr As String) As String
      
      If e Is Nothing Then
         Return errStr
      Else
         Return PrintError(e.InnerException, errStr + e.Message)
      End If 
   End Function 'PrintError
   
   'Entry point which delegates to C-style main Private Function
   Public Overloads Shared Sub Main()
      Run(System.Environment.GetCommandLineArgs())
   End Sub 'Main 
   
   
   Overloads Public Shared Sub Run(args() As String)
      
      If args.Length <> 2 Then
         Console.WriteLine("Usage: xslt source stylesheet")
         Return
      End If
      
      Try
         
         'Create the XslTransform object.
         Dim xslt As New XslTransform()
         
         'Load the stylesheet.
         xslt.Load(args(1))
         
         'Transform the file.
         Dim doc As New XmlDocument()
         doc.Load(args(0))
         
         xslt.Transform(doc, Nothing, Console.Out)
      
      Catch xmle As XmlException
         Console.WriteLine(("ERROR: XML Parse error occured because " + 
PrintError(xmle, Nothing)))
      Catch fnfe As FileNotFoundException
         Console.WriteLine(("ERROR: " + PrintError(fnfe, Nothing)))
      Catch xslte As XsltException
         Console.WriteLine(("ERROR: The following error occured while 
transforming the document: " + PrintError(xslte, Nothing)))
      Catch e As Exception
         Console.WriteLine(("UNEXPECTED ERROR" + PrintError(e, Nothing)))
      End Try
   End Sub
End Class 'Transformer

XSLT 样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:b="urn:xmlns:25hoursaday-com:bookstore">

<xsl:template match="b:bookstore">
<book-titles>
<xsl:apply-templates select="b:book/b:title"/>
</book-titles>
</xsl:template>

<xsl:template match="b:title"> 
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>

输出

<?xml version="1.0" ?>
<book-titles xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
xmlns:ext="urn:my_extensions" xmlns:b="urn:xmlns:25hoursaday-com:bookstore">
<title xmlns="urn:xmlns:25hoursaday-com:bookstore">The Autobiography of 
Benjamin Franklin</title>
<bk:title xmlns="urn:xmlns:25hoursaday-com:bookstore" 
xmlns:bk="urn:xmlns:25hoursaday-com:bookstore">The Confidence 
Man</bk:title>
</book-titles>

请注意,该样式表中的命名空间声明结束于输出 XML 文档的根节点上。另请注意,XSLT 命名空间未包括在输出 XML 文档中。

从 XSLT 转换的输出结果生成 XSLT 样式表有些麻烦,这是由于处理器必须能够从实际的样式表指令确定输出元素。我发现可以通过两种方法来解决此问题,我将通过显示一些样式表来阐释这两种方法,这些样式表生成下面的 XMLT 样式表作为输出结果。

<xslt:stylesheet version="1.0" 
 xmlns:xslt="http://www.w3.org/1999/XSL/Transform">
<xslt:output method="text"/>
<xslt:template match="/"><xslt:text>HELLO WORLD</xslt:text></xslt:template>
</xslt:stylesheet>

第一种方法涉及到创建一个包含要创建的样式表的变量,然后结合使用 value-of 和 disable-output-escaping 属性来创建该样式表。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml"  encoding="utf-8"/> 
  <xsl:variable name="stylesheet">
 &lt;xslt:stylesheet version="1.0" 
 xmlns:xslt="http://www.w3.org/1999/XSL/Transform"&gt;
&lt;xslt:output method="text"/&gt;
&lt;xslt:template match="/"&gt;&lt;xslt:text&gt;HELLO 
WORLD&lt;/xslt:text&gt;&lt;/xslt:template&gt;
&lt;/xslt:stylesheet&gt;
 </xsl:variable> 
 <xsl:template match="/">
  <xsl:value-of select="$stylesheet" disable-output-escaping="yes" /> 

  </xsl:template>
  </xsl:stylesheet>

如果所创建的样式表可以方便地进行分区,以便放在变量中,则第一种方法非常有效。尽管此方法快速方便,但是它还会归入杂项 类别,这在面临需要灵活性的任何情况时往往会变得难以处理。例如,如果在创建新样式表时涉及到创建许多动态文本并且与样式表指令交叉在一起,则相对于上面提到的杂项,以下方法会更适合。

<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
 xmlns:alias="http://www.w3.org/1999/XSL/Transform-alias">
  <xslt:output method="xml"  encoding="utf-8"/> 

 <xslt:namespace-alias stylesheet-prefix="alias" result-prefix="xslt"/> 

 <xslt:template match="/">
 <alias:stylesheet version="1.0">
<alias:output method="text"/>
<alias:template match="/"><alias:text>HELLO 
WORLD</alias:text></alias:template>
</alias:stylesheet>
  </xslt:template>

  </xslt:stylesheet>

上面的文档使用 namespace-alias 指令,将 alias 前缀及其所绑定到的命名空间名称替换为 xslt 前缀及其所绑定到的命名空间名称。

命名空间还用于指定扩展 XSLT 的机制。可以创建执行方式与 XSLT 函数相同的、带有命名空间前缀的函数。同样,某些命名空间中的元素可被视为对 XSLT 的扩展,并且可以像执行转换指令(如 template、copy、value-of 等)那样执行。下面是 Hello World 程序的示例,该程序使用基于命名空间的扩展函数来打印签名问候语。

<stylesheet version="1.0" 
 xmlns="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
 xmlns:newfunc="urn:my-newfunc">
 <output method="text"/>

<template match="/">
 <value-of select="newfunc:SayHello()" />
</template>

 <msxsl:script language="JavaScript" implements-prefix="newfunc">
        function SayHello() {
           return "Hello World";
        }
 </msxsl:script>
</stylesheet>
 

XML 命名空间警告

与任何有用的工具一样,XML 中的命名空间可能会被错误地使用,而且它还具有许多微妙之处,可能会产生问题(如果用户没有意识到这些微妙处)。本节重点介绍 XML 命名空间的用户通常会在哪些方面遇到问题或面临误解。

版本控制和命名空间

在实际中,主要有两种机制来创建不同版本的 XML 实例文档。一种方法是像在 XSLT 中那样使用根元素的 version 属性,另一种方法是将元素的命名空间名称用作版本控制机制。目前,基于命名空间的版本控制非常普遍,对于 W3C 尤其如此。W3C 已经将该机制用于各种 XML 技术,包括 SOAP、XHTML、XML 架构和 RDF。对于那些使用命名空间控制版本的文档,其命名空间 URI 通常采用如下格式:

http://my.domain.example.org/product/[year/month][/area]

通过修改后续版本中的命名空间名称来控制 XML 文档的版本有一个主要问题,那就是这意味着处理这些文档的、能够识别 XML 命名空间的应用程序将不再处理这些文档,并且将必须进行升级。这主要有益于版本不经常更改的文档格式,但是如果在更改版本时会修改元素和属性的语义,则会要求所有的处理器不再处理新版本,以防对它们产生错误理解。

另一方面,在许多情况下,让 XML 文档的版本控制机制基于根元素的 version 属性就足够了。version 属性主要有益于文档结构的更改可以向后兼容的情况。在以下情况下,使用 version 属性都是非常明智的选择:

•

元素和属性的语义将不会被修改。

•

对文档进行更改时涉及到添加元素和属性,但是很少涉及到删除它们。

•

应用程序与各种版本的处理软件之间的互操作性是必需的。

这两种版本控制方法不是互斥的,它们可同时使用。例如,XSLT 既使用根元素的 version 属性,又使用版本控制的命名空间 URI。version 属性用于对 XML 文档格式进行递增式向后兼容的更改,而修改命名空间名称是为了对文档的语义进行重大的更改。

文档类型

正如在几个有关各种 XML 相关邮件列表的哲学争论中讨论的那样,术语文档类型 容易引起误解。在许多情况下,根元素的命名空间名称可用于确定如何处理文档,然而,这很难成为一个一般性规则,并且如此声明会违反 XML 命名空间的精神,因为它们在设计上完全是为了让开发人员能够混合和匹配 XML 词汇表。

Rick Jelliffe 有关 XML-DEV 的帖子简明扼要,它抓住了为什么认为根命名空间的 URI 等同于文档类型概念这一问题的本质。这个帖子的本质是,一个 XML 文档可以有许多不同的类型,包括它的文档类型(由它的文档类型定义 (DTD) 指定)、它的 MIME 媒体类型、它的架构定义(由 xsi:schemaLocation 属性指定)、它的文件扩展名以及它的根元素的命名空间名称。因此,在许多情况下,根据用户从哪个角度来检查文档,一个文档将很有可能有许多不同的类型。

RDDL 文档(示例,请注意,它的根元素来自 XHTML 命名空间)和批注的映射架构(它们的根元素来自 W3C XML 架构命名空间)是 XML 文档的两个示例,在这些示例中,如果只是查看根元素的命名空间 URI,就会曲解实际文档类型。

一言以蔽之,不能通过查看文档根元素的命名空间 URI 来最终确定文档的类型。一定要进行思考,否则是非常愚蠢的。

 

命名空间的未来

在 XML 领域中,有许多开发都侧重于处理围绕 XML 命名空间开发而产生的一些问题。首先,当前的 W3C XML 命名空间建议的草案没有为取消对已映射到前缀的命名空间的声明提供机制。W3C XML 命名空间 v1.1 工作草案将提供一种机制来取消对实例文档中前缀-命名空间映射的声明,以纠正这种疏忽。

对于在试图取消引用命名空间 URI 的内容时应当返回什么内容存在着争论,这导致在 XML 领域中引起富有争议的辩论,并且还成为 W3C 的 Technical Architecture Group 目前争论的焦点。当前版本的 XML 命名空间建议不要求命名空间 URI 实际上是可解析的,因为命名空间 URI 应当只是一个用作唯一标识符的命名空间名称,而不是资源在 Internet 上的位置。

Tim Bray(XML 语言和 XML 命名空间建议最初的编辑之一)已经撰写了一篇详尽的论文,论述有关命名空间 URI 和命名空间文档的问题,可以(或者也许不可以)从 URI 中检索到这些文档。此文包含在创建资源目录描述语言 (RDDL) 时涉及到的许多推理。RDDL 设计用于创建命名空间文档。

Dare Obasanjo 是 Microsoft 的 WebData 组的成员,该小组在 .NET 框架的 System.Xml 和 System.Data 命名空间、Microsoft XML 核心服务 (MSXML) 和 Microsoft 数据访问组件 (MDAC) 中开发组件。

有关本文的任何问题或评论,欢迎张贴到 GotDotNet 上的 Extreme XML 留言板。

【零基础入门unity游戏开发——unity通用篇14】unity特性相关的知识(基于unity6开发介绍) unity特性相关的知识(基于unity6开发介绍) 阅读详情

相关推荐

避坑实录:用certificate-manager重置vCenter 6.7证书时遇到的三个致命陷阱

本文详细解析了使用certificate-manager重置vCenter 6.7证书时可能遇到的三大致命陷阱,包括进度卡在85%的服务启动僵局、脚本突然退出的静默杀手以及密码错误锁死的隐藏机制。通过实战验证的解决方案和高级恢复技巧,帮助系统管理员有效避免vCenter环境瘫痪,确保证书更新过程顺利进行。

g5h6i7j的博客 919

关于XML中的命名空间介绍

这里,命名空间前缀是 cont,标示符(URI)是 www.tutorialspoint.com/profile。这意味着,带有 cont 前缀元素名和属性名都(包括 contact 元素)属于 www.tutorialspoint.com/profile 这个命名空间。在XML中,名称空间的使用涉及范畴的概念,范畴即名称空间的覆盖范围,它指的是哪些元素和属性在该名称空间中,哪些不在该名称空间中。这篇文章主要介绍了XML的命名空间,包括命名空间的声明等XML入门学习中的基础知识,需要的朋友可以参考下。

xiaoweids的博客 1220

STM32CubeMX Nucleo F767ZI 教程(1)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 官网上买了个NUCLEO F767ZI 的开发板,144引脚的芯片,https://www.st.com/content/st_com/zh/products/evaluation-tools/prod

fafuwxm 2029

xml----命名空间详解

xml 命名空间xmlns详解

qq_41768644的博客 2576

【天线与电波传播】电波传播部分 第7章 电波传播的基础知识3

菲涅尔区与菲涅尔带的基本知识

Chen59_2328的博客 1601

拆解一个800G光模块:手把手带你认识里面的MT插芯和光纤阵列(FA)

本文详细拆解了800G光模块中的关键组件MT插芯和光纤阵列(FA),揭示了并行光学技术如何实现高速数据传输。通过显微镜下的精密观察,展示了MT插芯的高精度构造和光纤阵列的连接奥秘,同时解析了高精度研磨工艺对光信号传输的重要性。这些微型组件是高速收发模块实现800Gbps带宽的核心技术。

weixin_30839881的博客 1549

XML 命名空间

xml-了解 XML 命名空间减小字体 增大字体 本页内容什么是命名空间? 编程语言中的命名空间 XML 中的命名空间 对命名空间进行命名 定义命名空间 使用命名空间 命名空间抽象 小结 由 Aaron Skonnard 撰写的“了解 XML 命名空间”最初刊登在 2001 年 7 月的 MSDN Magazine 中。此更新版本的使用经过授权。版权所有 ? 2001 Microsoft Corp

ZiMinqun的专栏 1217

simulink求解器选择的小tip

给出了simulink选择求解器的一种tip,与积分初值有关。

高能阿博特的博客 2054

XML命名空间详解

文章目录XML文件命名空间定义解释 XML文件命名空间 观察下面这个xml文件(spring框架文件头): <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springfram

weixin_43790613的博客 4591

TOGAF架构内容—TOGAF 内容框架和企业元模型

TOGAF架构内容—TOGAF 内容框架和企业元模型

深圳市多克创新科技有限公司 1664

【JCR一区级】鱼鹰算法OOA-CNN-LSTM-Attention故障诊断分类预测【含Matlab源码 5711期】

鱼鹰算法OOA-CNN-LSTM-Attention故障诊断分类预测 完整代码和数据,方可运行;数据可直接替换,适合小白!可提供运行操作视频!

订阅付费专栏Matlab(奶茶价版)或下载付费资源,可赠送奶茶价版付费专栏指定代码1份; 3601

XML命名空间以及它们如何影响XPath和XSLT(Extreme XML)

XML命名空间以及它们如何影响XPath 和XSLT(Extreme XML)本文专门阐释由 Microsoft 支持的 W3C XML 技术的更微妙的内容。尽管 XML 的核心仍相当简单,但是围绕它的技术已经变得日益复杂,而且其中的一些技术需要相当多的专业知识才能掌握。本文旨在将各种 W3C XML 建议中的信息提取为便于理解的信息,供 XML 用户和开发人员使用。在这一文章中,主要是有关 XM

cool_rain_man的专栏 1097

华为OD机试双机位A卷 - VLAN资源池 (C++ & Python & JAVA & JS & GO)

华为OD机试2025双机位A卷 VLAN资源池,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 879

XML 命名空间以及它们如何影响 XPath 和 XSLT

Dare Obasanjo Extreme XML 讨论了 XML 命名空间的详细内容以及它们在许多 XML 技术上的分支点击此处阅读全文

1182

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Web开发:xmlns解析

Web开发:xmlns解析

Weiki的博客 1723

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

xml文档的头部说明

近来学习xml文档, 对于头部的用法不是特别理解 整理一下思路, 如果有错误欢迎指出 xml文档一定要有一个根元素 使用默认命名空间 为什么要使用命名空间? 避免因为相同标签名 而产生冲突 为什么要用默认命名空间? 该元素内部的子元素都会默认属于该命名空间下, 不需要再为它们添加命名空间。 命名空间为什么使用URL? 因为短的变量名比如 a b c 重复可能性极高, 而URL长度长, 且唯一 如: (例子来自XML 命名...

mobeiCanyue 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

关于XML名称空间(命名空间)

名称空间的作用? 为了解决不同领域的XML词汇的同名冲突和区分识别。(参考底下的示例) 注意:名称空间只存在逻辑意义,无法真正实现对URI的引用。 名称空间的声明: 放在元素(一般是根元素)的起始标签内,以类似属性的形式声明。 名称空间的声明将名称前缀和URI关联起来。 名称空间的作用范围: 只在声明名称空间的元素以及该元素所包含的元素和属性内有效。 (注意:默认名称空间不直接作用于属性) 声明名称空间的元素,称为包容体(Container)。名称空间和前缀的关联关系在包容体的

weixin_46381351的博客 4553

XML命名空间

XML命名空间(XML namespace,也译作XML名称空间、XML名字空间)用于在一个XML文档中提供名字唯一的元素和属性。XML命名空间在W3C推荐规范《Namespaces in XML》中定义。XML命名空间于1999年1月14日成为W3C的推荐规范。 W3C将XML命名空间定义为以国际化资源标识符(Internationalized Resource Identifier,IR

岁月静好 1919

.NET转换xslt xml 时某些元素包含xmlns=""的问题

<br />例如:<h1 xmlns="">精舞门</h1><br /><br />按w3c规则,使用xslt转换时,如果指定了除xmlns:xsl外其它的命名空间,在使用<xsl:element   生成新节点时,就会自动加上这个命名空间。<br />估计这个“其他命名空间”也包括了<html>的xmlns,这样子我们就在<xsl:stylesheet>上再加一句<br />xmlns="http://www.w3.org/1999/xhtml",并去掉 <html>上的xmlns,就没问题了<br />

pdckxd的专栏 1206

Xml_Schema命名空间详解

1. Xml命名空间 1.1 XML命名空间XML Namespaces XML 命名空间提供避免元素命名冲突的方法。XML命名空间属性被放置于元素的开始标签之中,并使用以下的语法: xmlns:namespace-prefix="namespaceURI" 举例   当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。

turboj的博客 3908

xml命名空间详解

在研究spring security的时候,里面提到了一个重要的感念就是命名空间,当时以为是spring的一个什么特殊功能,后来研究后才发现是xml的一个知识点,顺便又研究了一下这个知识,找到一篇文章感觉挺好,在此做个记录。 转自:http://bbs.actionscript3.cn/thread-1556-1-1.html 关于命名空间有很多人回避。认为太难。其实命名空间使用很普遍,在...

caozuiba 409

XML配置文件的命名空间

XML配置文件的命名空间

chenweibbxx的博客 474
上一篇: XML 中的常见问题
下一篇: 反向链接简介
AngelGavin
博客等级 码龄24年 2粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值