本站首页    管理页面    写新日志    退出

The Neurotic Fishbowl

[/*SemanticWeb*/][转]将XML文档与XInclude 合并在一起
nybon 发表于 2004/12/23 8:21:00

将 XML 文档与 XInclude 合并在一起 发布日期: 5/20/2004 | 更新日期: 5/20/2004 Oleg Tkachenko 2004 年 4 月 适用于: 可扩展标记语言 (XML) 1.0 Microsoft .NET 框架 摘要:本文探讨了如何从多个文档构造单个 XML 文档的问题。它重点讨论了 XML Inclusions (XInclude),这是一种便于您用 XML 实现模块化的多用途机制。(15 页打印页) 下载 XInclude.NET-1.2.exe 示例代码。 500)this.width=500'> 本页内容 500)this.width=500'> 简介 500)this.width=500'> 为什么要使用 XInclude? 500)this.width=500'> 50,000 英尺以外的 XInclude 500)this.width=500'> XInclude 语法 500)this.width=500'> XInclude 处理模型 500)this.width=500'> XPointer 500)this.width=500'> XInclude 用法实践 500)this.width=500'> 小结 500)this.width=500'> 致谢 简介 模块化编程的思想要求您将任务细分成小的可管理单位。这种思想也适用于制作 XML 文档。通常,从几个较小的文档生成一个大型文档是有意义的。需要这种模块化方法的一些情况包括:将多个章节编撰成一部书,从单独维护的文档生成网页,或将标准页脚(例如,公司的免责声明)添加到文档中。 有很多方法可以解决如何从多个文档构造出单个 XML 文档的问题。本文重点讨论一个方法,该方法注定是便于用 XML 实现模块化的通用多用途机制:XML Inclusions (XInclude)。 500)this.width=500'>返回页首 为什么要使用 XInclude? 读者可能会问的第一个问题是:“为什么要使用 XInclude,而不是 XML external entities?”答案是,XML 外部实体有很多众所周知的局限和不便于使用的含义,这些因素极大地妨碍了 XML 外部实体成为多用途包含工具。具体来说: • XML 外部实体无法成为一个成熟的独立 XML 文档,因为它既不允许独立的 XML 声明,也不允许 Doctype 声明。这实际上意味着 XML 外部实体本身无法包括其他外部实体。 • XML 外部实体必须是格式规范的 XML(第一眼看起来好象没有这么差,但想象一下怎样将示例 C# 代码包括到 XML 文档中)。 • 未能加载外部实体是重大错误 (fatal error);严格禁止任何恢复。 • 只能包括整个外部实体,无法只包括文档的一部分。 • 外部实体必须在 DTD 或内部子集中进行声明。这将打开有很多含义的潘多拉盒子,例如,这些含义可能是:要求文档元素必须在 Doctype 声明中命名,以及对读取方的验证可能需要在其他文档的 DTD 中定义文档的全部内容模型。 人们认识到将 XML 外部实体用作包含机制的缺点已经有一段时间了,实际上,这些缺点导致了在 1999 年由 Microsoft 和 IBM 将 XML Inclusion Proposal 提交到 W3C。该建议定义了一个多用途 XML 包含工具的处理模型和语法。 几年后,XML Inclusions(也称为 Xinclude)的 1.0 版本成为 Candidate Recommendation,这意味着 W3C 相信它已经被广泛审阅并且解决了它要解决的基本技术问题,但它还没有成为正式建议。 那么,XInclude 真的解决了上述问题吗?当然。让我们来看它是如何做到的。 500)this.width=500'>返回页首 50,000 英尺以外的 XInclude XInclude 定义了一个便于在 XML 文档中实现模块化的多用途包含机制。包括过程被正式定义为将很多 XML 信息集 (XML Infoset) 合并到单个复合的 XML 信息集中。作者通过包含指令来指定要合并哪些文档并控制合并过程。包含指令的 XInclude 语法基于大家熟悉的、容易产生和处理的 XML 构造:元素、属性和 URI 引用。 XInclude 支持包含非 XML 文本文档,并允许作者控制恢复过程。例如,您可以提供要包含的默认内容或备用文档,如果无法加载远程资源,就将包括这些默认内容或备用文档。 XInclude 还支持部分 XML 包含,也就是说,您可以定义(通过提供 XPointer 指针)应当包括 XML 文档的哪一(些)部分。 下面的基本 XInclude“Hello World”示例可以更清楚地演示这个机制。假如您有一些网页定义,并且想让它们全都包括带有公司版权信息的模板页脚: page.xml:<?xml version="1.0"?> <webpage> <body>Hello world!</body> <xi:include href="templates/footer.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/> </webpage> footer.xml:<?xml version="1.0"?> <footer>? Contoso Corp, 2003</footer> page.xml after XML Inclusion processing:<?xml version="1.0"?> <webpage> <body>Hello world!</body> <footer xml:base="templates/footer.xml">? Contoso Corp, 2003</footer> </webpage> 500)this.width=500'> 图 1“Hello World!”XInclude 示例。 下面是另一个介绍性示例,它演示了如何将外部非 XML 文本数据包含到 XML 文档中。假设您有一个存储在服务器上的 XML 文档,并且您想让它包含一个计数器,该计数器描述文档访问的次数:<?xml version="1.0"?> <catalog xmlns:xi="http://www.w3.org/2003/XInclude"> <p>This document has been accessed <xi:include href="http://www.contoso.com/Counter.aspx?pid=catalog" parse="text"/> times.</p> </catalog> 这是 XML Inclusion 处理后的文档:<?xml version="1.0"?> <catalog xmlns:xi="http://www.w3.org/2003/XInclude"> <p>This document has been accessed 45453 times.</p> </catalog> 500)this.width=500'>返回页首 XInclude 语法 XInclude 语法非常简单,只是在 http://www.w3.org/2003/XInclude 命名空间中的两个元素,即 include 和 fallback。常用的命名空间前缀是“xi”(但可以根据喜好自由使用任何前缀)。对于那些习惯使用正式语法定义的人,XInclude 规范提供了 XInclude 的 XML 架构和 DTD。对于其他人,下面是它的摘要: xi:include 元素 xi:include 元素充当包括指令。它定义了要包括哪些文档以及如何包括。它的属性是: • href — 对要包括的文档的 URI 引用。 • parse — 它的值可以是“xml”或“text”,用于定义如何包括指定的文档(是作为 XML 还是作为纯文本)。默认值是“xml”。 • xpointer — 这是一个 XPointer,用于标识要包括的 XML 文档部分。如果作为文本包括 (parse="text"),将忽略该属性。 • encoding — 作为文本包括时,该属性提供所包括文档的编码提示信息。 • 注 请回忆一下,通常,没有人可以说出任意一个文本文件的编码是什么。幸运的是,XML 不受这个问题的影响(因为如何检测 XML 文档的编码有严格的规则),这就意味着如果是作为 XML (parse="xml") 完成包括的,就可以忽略 encoding 属性。 • accept、accept-charset 和 accept-language — 这些属性可以用来帮助进行 HTTP content negotiation。当 XInclude 处理器通过 HTTP 协议取得资源时,它应当使用这些属性的值来设置 HTTP 请求中的 Accept、Accept-Charset 和 Accept-Language 头。如果对于相同的资源,单个 URI 可能基于 HTTP 头分析返回不同的表示形式(比如说,原始 XML 或 XHTML、ISO88591 或 UTF-8 编码、英语版本或希伯来文版本),那么该工具应该针对一种情况。 xi:include 元素可能只包含一个可选的 xi:fallback 元素,任何其他内容仅仅被忽略。 xi:fallback 元素 xi:fallback 元素提供了一个在丢失资源后恢复的机制。如果要包括的资源由于任何原因(连接问题、安全限制、资源不存在、URI 架构未知或者像 mailto: 一样不可获取,等等)而不可用,那么将包括 xi:fallback 元素的内容。下面的示例显示了如何使用 xi:fallback 元素: <page xmlns:xi="http://www.w3.org/2003/XInclude"> <header>New This Week from MSDN</header> <xi:include href="http://msdn.microsoft.com/rss.xml"> <xi:fallback>Sorry, MSDN news are unavailable.<xi:fallback> </xi:include> </page> 如果资源丢失并且 xi:include 元素为空,则不会包括任何内容。xi:fallback 元素没有属性,它必须是 xi:include 元素的直接子集,并且它的内容是不受限制的。由于对 xi:fallback 元素的内容没有限制,因此,它就可以包含另一个 xi:include 指令,从而提供要包括的可选恢复资源:<page xmlns:xi="http://www.w3.org/2003/XInclude"> <header>New This Week from MSDN</header> <xi:include href="http://msdn.microsoft.com/rss.xml"> <xi:fallback> <xi:include href="http://msdn.microsoft.com/xml/rss.xml"> <xi:fallback>Sorry, MSDN news are unavailable.<xi:fallback> </xi:include> <xi:fallback> </xi:include> </page> 保存基本 URI 留心的读者可能已经注意到出现在结果文档中的 xml:base 属性。这是一个重要的功能,当文档被包括到另一个文档(可能在其他位置)中时,它可以防止在被包括的文档中的相对 URI 引用被破坏。请参考下例。 位于 C:\Contoso\Inventory 目录中的 parts.xml 文档使用相对 URI 引用来引用相同目录中的 XML 架构 parts.xsd:<parts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="parts.xsd"> <part SKU="10023" quantity="100"/> </parts> 位于 C:\Contoso\Reports 目录中的 report.xml 文档包括 parts.xml:<report> <inventory> <xi:include href="C:\Contoso\Inventory\parts.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/> </inventory> </report> 经过 XML Inclusion 处理之后,report.xml 文档如下所示:<report> <inventory> <parts xmlns:xsi="http://www.w3.org/2003/XMLSchema-instance" xsi:noNamespaceSchemaLocation="parts.xsd" xml:base="../Inventory/parts.xml"> <part SKU="10023" quantity="100" /> </parts> </inventory> </report> 注意 xml:base 属性是如何保存被包括文档的基本 URI 的,该属性使 xsi:noNamespaceSchemaLocation 属性中的相对 URI 引用指向位于 C:\Contoso\Inventory 目录中的相同架构文件。 500)this.width=500'>返回页首 XInclude 处理模型 从技术上讲,XInclude 将包含定义为特殊类型的 XML 信息集转换。源信息集转换为结果信息集后,在结果信息集中每个 xi:include 元素被替换为它引用的信息集。该过程也可以被看作是信息集的合并。 XML Inclusion 是一个递归过程,因此,还会处理被包含文档中的每个 xi:include 元素。当然,为了保证安全,循环包含将会被检测,并将其当作重大错误。什么是重大错误?XInclude 定义了两种类型的错误,这两类错误都可能在包含过程中发生:“重大错误”,可以想象它是指出现了使正常处理过程无法继续的因素;和“资源错误”,这是指获取资源的尝试失败。重大错误是致命的,这就意味着处理过程必须停止,而资源错误则可后进行处理。 现在来看看如何处理 xi:include 元素。首先,它依赖于 parse 属性值。当 parse="xml" 时(顺便说一句,这是默认值),获取引用的文档,并将该文档解析为 XML,然后替换源信息集以及其后代中的 xi:include 元素。可以设想,试图包含格式不规范的 XML 文档将导致重大错误,因为格式的规范性是 XML 的“圣杯”(译注:Holy Grail — 圣杯/圣盘,据中世纪传说为基督在最后的晚餐上用过的那个杯或盘子,后来成为许多骑士追求的目标,此处是指格式的规范性是编写 XML 文档时追求的目标)。 如果 parse="text",将获取引用的文档,并将它视为纯文本,然后以同样方式替换 xi:include。这是非常有用的功能,例如,它允许将源代码或 XML 文档作为文本进行包含。如下示例显示了将 XML 文档作为文本包含在另一个文档中:<doc xmlns:xi="http://www.w3.org/2003/XInclude"> For instance, consider the following SOAP message request to the Contoso Delivery Web Service: <xi:include href="contoso-soap.xml" parse="text"/> </doc> 执行 XML Inclusion 之后,结果文档如下所示:<doc xmlns:xi="http://www.w3.org/2003/XInclude"> For instance, consider the following SOAP message request to the Contoso Web Service: &lt;?xml version="1.0" encoding="utf-8"?> &lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> &lt;soap:Body> &lt;Delivery xmlns="http://www.contoso.com"> &lt;address> &lt;Street>One Microsoft Way&lt;/Street> &lt;City>Redmond&lt;/City> &lt;Zip>98052&lt;/Zip> &lt;/address> &lt;/Delivery> &lt;/soap:Body> &lt;/soap:Envelope> </doc> 注意左尖括号字符被转义,因为整个 contoso-soap.xml 文档(尽管它是 XML)是作为单个文本节点被包含的。 在另一个文本包含可能有用的有趣事例中,您希望在 XSL 转换期间包含某个外部文本文档。虽然 XSLT 1.0 有 document() 函数,但该函数只允许您打开外部 XML 文档,而不能打开纯文本文档。例如,要将 CSS 文件包含到生成的 HTML 文档中,只要一个 xi:include 指令就足够了:<xsl:template match="page"> <html> <head> <style type="text/css"> <xi:include href="main.css" parse="text"/> </style> ... 由于显而易见的原因,您仍然无法用该方式包含二进制资源。试图包含 XML 1.0 建议所不允许的字符将导致重大错误。 500)this.width=500'>返回页首 XPointer 到此为止,都很顺利。上面提供的示例说明了如何包含整个文档,但如果只需包含文档的一部分(比如说,包括某个书籍目录中特定作者的所有书籍),又该怎么办呢?请输入 XPointer。XInclude facilitates partial inclusion using XPointer pointers in xpointer attribute: <para> My favorite books are: <xi:include href="books.xml" xpointer="xpointer(//book[@author='Stephen King'])"/> </para> 上面的指令包含了所有 book 元素,它们的 author 属性值是来自 books.xml 文档的“Stephen King”。圆括号中的表达式您应当非常熟悉。它是 XPath 吗?不完全对,但非常接近。它是特殊类型的 XPointer,或更准确地说,是指向特殊 XPointer 架构 xpointer() 的指针,而 xpointer() 是 XPath 的扩展。现在让我们循序渐进地看一看 XPointer 的原理。 XPointer 代表“XML 指针语言”,它是用于进行 XML 寻址的可扩展的系统。XPointer 的基础是 XPointer 框架,后者定义了段落标识符的语义和基本语法。XPointer 框架定义了两种类型的指针:快捷 (shorthand) 指针和基于架构 (scheme-based) 指针。 快捷指针(以前称为 barename)事实上是对HTML 中段落标识符的大致模拟,后者指向命名定位点。而 XPointer 快捷指针最多只能按元素 ID 标识 XML 文档中的一个元素。ID 可以由 DTD、XML 架构或以应用程序特有的方式确定。<xi:include href="books.xml" xpointer="bk101"/> xpointer 属性中的 bk101 值就是一个快捷 XPointer 指针,它标识了 books.xml 文档中的某个元素,该元素的 ID 是“bk101”。 基于架构的指针是更复杂的指针类型,它由指针部分的序列组成,并可选择用空格分开。每个指针部分有一个架构名称和一些放在圆括号中的、架构特有的数据,例如 element(bk101) 或 xpointer(//book):<xi:include href="books.xml" xpointer="element(bk101)xpointer(//*[@title='Dreamcatcher'])"/> 在以前的包含指令中,xpointer 属性值表示基于架构的 XPointer 指针,该指针标识了在 books.xml 文档(其 ID 是 bk101)中的元素,或者如果无法找到这样的元素,则它标识其 title 属性值是 Dreamcatcher 的元素。 500)this.width=500'> 图 2基于架构的 XPointer 指针结构 指针部分是按从左到右的顺序计算的,直到某个部分识别出某个子资源。无法识别或不被支持的部分将被忽略。但要注意,如果整个指针中没有任何指针部分能够识别子资源,则会发生错误。快捷指针同样如此。 如您所见,基于架构的指针提供了一种使段落标识更可靠的方式,因而允许您指定几个指针部分,其中每个部分可以按不同方式指向希望的子资源。如果指针部分未能识别子资源,则继续计算下一个指针部分,实际上提供某种替换的寻址行为。 XPointer 架构 W3C 定义了三种类型的 XPointer 架构,即 element()、xmlns() 和 xpointer()。另外,Simon St.Laurent 建议 xpath1() scheme,该架构使用规则的 XPath 1.0 语法,就像在 xpath1(//book) 中一样。 此 element() 方法便于按 ID(就像快捷指针一样)和按同辈元素之间的位置编号进行基本的 XML 元素寻址。例如,element(/1/3) 指针部分标识了根元素的第三个子元素,而 element(bk101/2) 则标识了 ID 为 bk101 的元素的第二个子元素。 xmlns() 架构表示辅助指针部分,它永远不标识自己的任何子资源,但允许定义绑定了其他指针部分的上下文的命名空间(这样,就可以根据需要将任意多个指针部分组合在一起)。例如,下面的 XPointer 指针标识了在属于“http://www.contoso.com”命名空间的文档中的所有 book 元素:xmlns(co=http://www.contoso.com)xpointer(//co:book) xpointer() 架构的功能最强大。它为对 XML 文档的各部分进行寻址提供了高级别的功能。它基于 XPath 1.0,并将 XPath 扩展为允许对字符串、点和范围进行寻址。请注意,xpointer() 架构仍然在发展,并且很可能有进一步的变化。 现在回到对 XInclude 的讨论。XInclude 规范要求任何符合规范的 XInclude 处理器都必须支持 XPointer 框架和 element() 架构。这实际上意味着您只能安全地使用文档中的快捷指针和基于 element() 架构的指针,但既然 Xinclude 还在发展之中,所以最好经常查阅 XInclude 处理器的文档。 我们已经讨论完理论部分。现在谈谈实践中如何编程。 500)this.width=500'>返回页首 XInclude 用法实践 我们首先需要支持 Xinclude 的环境。不要指望您喜欢的 XML 语法分析程序自动支持 XInclude。例如,很遗憾 MSXML 和 System.xml 都不支持 Xinclude。W3C 在 XInclude Implementations Report 中列出了可用的 XInclude 实现。其中一些实际上仅用于实验,但有几个具有生产水准。 我最喜欢的 XInclude 实现 XInclude.NET,这可能因为我是此项目的首席开发人员。 用于 .NET 的 XInclude — XInclude.NET XInclude.NET 项目受到 Chris Lovett 的 XInclude, Anyone? 一文启发,发现这篇文章时,我正在解决类似的问题:如何利用由不同团队分别编写的文档编撰出网页。通过方便地利用 .NET 框架的强大功能,可以在 System.Xml API 之上建立健壮、高性能的 XInclude 处理器。XInclude.NET 库的 1.2 版本最近已经发布,现在用户可以判断是否已实现该目标。 XInclude.NET 项目是 2003 年 11 月 10 日发布的 XInclude 1.0 Last Call Working Draft (编写本文时的最新版本)的实现,是用 .NET 框架的 C# 编写的。此外,它支持 XPointer 框架、element()、xmlns()、xpath1() 和 xpointer()(仅 XPath 子集)架构。本文所附的代码示例包含 XInclude.NET 1.2 版本,该版本提供了预编译的 XInclude.dll 程序集、API 文档、示例和 XInclude 实现的源代码。 XInclude.NET 中的关键类是 XIncludingReader,可以在 GotDotNet.XInclude 命名空间中找到它。主要设计目标是为 XML 处理建立可插接的流管道。为了实现这个目标,XIncludingReader 实现了一个 XmlReader,该 XmlReader 可以围绕在另一个 XmlReader 的周围。该体系结构允许在不作任何重大修改的情况下将 XInclude 处理层很容易地插入到各种应用程序中。例如,当 XML 正在加载到 XmlDocument 中时,如果要启用对该 XML 的 XInclude 处理,只需用 XIncludingReader 将 wrapXmlTextReader 包装起来:using System.Xml; using GotDotNet.XInclude; public class Class1 { public static void Main(string[] args) { XmlTextReader r = new XmlTextReader("document.xml"); XIncludingReader xir = new XIncludingReader(r); XmlDocument doc = new XmlDocument(); doc.Load(xir); //... } } 在执行 XSL 转换之前的 XML Inclusion 是同样简单的:using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; using System.IO; using GotDotNet.XInclude; public class Class1 { public static void Main(string[] args) { XIncludingReader xir = new XIncludingReader("document.xml"); XPathDocument doc = new XPathDocument(xir); XslTransform xslt = new XslTransform(); xslt.Load("stylesheet.xslt"); StreamWriter sw = new StreamWriter("result.html"); xslt.Transform(doc, null, sw); sw.Close(); } } 前面显示的 CSS 包含的示例假定 XSLT 样式表由 XInclude 处理器处理;以下代码显示了如何完成该操作:public class Class1 { public static void Main(string[] args) { XPathDocument doc = new XPathDocument("document.xml"); XslTransform xslt = new XslTransform(); XIncludingReader xir = new XIncludingReader("stylesheet.xslt"); xslt.Load(xir); StreamWriter sw = new StreamWriter("result.html"); xslt.Transform(doc, null, sw); sw.Close(); } } XML Inclusion 过程与 XML 语法分析、验证或转换没有关系。这实际上意味着由您决定在什么时候允许 XML Inclusion 发生:是在语法分析之后,但在验证之前;还是在验证之后,但在转换之前,甚至在转换之后。 注 在执行 XML Inclusion 期间保存基本 URI 意味着在结果文档中会出现 xml:base 属性。这实际上意味着在“预验证包含”方案中 XML 架构作者应当期望 xml:base 属性出现在所包括的元素的最上层。实际上,xml:base 属性是核心标准 XML 属性,所以在这里有必要允许在架构中对每个元素包含 xml:base 属性。 XIncludingReader 如何工作 注 必须熟悉 XmlReader 体系结构。否则可以跳过本节。 XIncludingReader 实现基于 XmlReaders 链 (chaining) 技术,.NET Framework Developer's Guide 中的 Customized XML Reader Creation 一节对此进行了描述。该技术与旧式 SAX 筛选很相似,它允许通过委托调用将 XmlReaders 进行链化,从而有效地提供高性能的方法来筛选或修改 XML(当 XML 正在被读取时)。 500)this.width=500'> 图 3 一条 XmlReaders 链 XIncludingReader 总是工作在另一个读取器(SAX 术语叫“父”读取器,它为 XIncludingReader 提供输入 XML 流)之上。当 XIncludingReader 的输入与 XmlReader 不兼容时(如在 System.IO.Stream 或 System.IO.TextReader 中),将实例化一个临时 XmlTextReader 对象来充当父读取器。所得到的 XML(在完成 XML Inclusion 的位置)可以被 XIncludingReader 自己的客户端应用程序读取;记住,它只是 XmlReader。 大多数时候,XIncludingReader 不做任何事情;它只是向父读取器委派方法调用,并透明地公开父读取器的属性(例如,名称或值)来作为它自己的属性。虽然这样,但它总是监视父读取器所报告的 XML 元素的名称。一旦将父读取器放在 xi:include 元素上,XIncludingReader 就会被激活并开始执行包含过程。 父读取器并不会将 xi:include 元素公开给客户端应用程序,而是被压入堆栈,并实例化新的临时 XmlReader 以读取 xi:include 指令所引用的文档。该临时读取器的实际类型取决于是否存在 xpointer 属性(如果是这样,它会成为一个专用的 XPointerReader,它将实现 XPointer 并只读取指针节点所标识的内容),或者取决于包含操作是否是在文本模式下完成的(如果是这样,它会成为一个专用的 TextIncludingReader,它将把整个文档作为单个文本节点进行读取)。否则,它的行为只像一个 XmlTextReader。 不管怎样,父读取器都将被压入堆栈,而这个新的读取器会成为父读取器。普通读取会继续进行下去,直到从父读取器读取不到输入。之后,包括过程执行完毕,并且前一个父读取器从堆栈中弹出。 虽然这听起来很简单,但请记住这只是冰山一角。隐藏的部分超出了本文的范围,这些部分包括实现后备处理和极其重要地公开 XmlReader API 中的综合 xml:base 属性(Martin Gudgin 在他的网络日记中对此进行了详细介绍)。如果想要了解更多内容,只需深入阅读源代码。另外,请在该项目的 message board 上大胆地询问任何与 XInclude.NET 有关的问题,并将错误提交到 bug tracker。 这样的仅向前、非缓存的流实现会占用非常少的内存,并且几乎不会对性能造成任何不利影响。在大多数时间里,XIncludingReader 所做的全部操作只是比较元素的名称、监视 xi:include 元素。在考虑到 XmlNameTable 的情况下,假设比较已经完成,这将是非常廉价的操作(因此,在 99% 的情况下这只是对两个对象指针进行的比较)。 遗憾的是,对 XPointer 指针的处理并不是低成本的。事实上,它需要将整个包含的文档加载到内存中,只是为了按 ID、XPath 选择路径或按 xpointer() 指针选择所需的部分。有趣的是,对 XPointer 指针的计算是通过将 XPointer 语法转换成 XPath 表达式在内部实现的,如下所示: 1. 快捷指针被转换成 id() function 调用:从 bk101 到 id('bk101')。 2. 基于 element() 架构的指针被转换成 XPath 选择路径,其中包含 id() 函数调用和/或位置谓词:从 element(bk101)/3 到 id('bk101')/*[3]。 3. 基于 xpointer() 架构的指针被直接用作 XPath 表达式。这就是为什么 XInclude.NET 不支持 XPath 的 xpointer() 超集的原因。 未来的 XInclude.NET 版本可能提供更完整和更有效的 XPointer 实现。 500)this.width=500'>返回页首 小结 XInclude 是正在发展的 W3C 标准,旨在便于实现 XML 中的模块化。它定义了对 XML 文档进行多用途包含或合并时所需的处理模型和语法。它不依赖于 XML 语法分析和验证,并且它的语法基于 XML 元素、属性和 URI 引用。 尽管 XInclude 还不是 W3C 推荐标准,但它的实现数量以及它在 XML 社区受到的欢迎正在不断增长。在本文中,我们已经介绍了 XInclude 和 Xpointer。我们还会讨论针对 .NET 框架的具体的 XInclude 实现。 500)this.width=500'>返回页首 致谢 我十分感谢 Dare Obasanjo 在我准备本文时提供的全部帮助。 转到原英文页面

阅读全文(3113) | 回复(0) | 编辑 | 精华

 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)

 
 



The Neurotic Fishbowl

.: 公告

This blog focuses on:

Semantic Web && Java Technology


Bloginess

«October 2025»
1234
567891011
12131415161718
19202122232425
262728293031

.: 我的分类(专题)

首页(171)
/*SemanticWeb*/(34)
/*Java*/(74)
/*FreeComments*/(59)
/*Agent*/(4)


In the Bowl

.: 最新日志

The End
使用Google Trends进行选型
怎样才能称为一次新的版本发行?
如何防止RSS信息过载
使用Excel作为用户接口
如何有效地报告Bug
sourceforge再次被封
趣文两篇
编写Firefox扩展
Jetspeed心得随笔


.: 最新回复

回复:Google API与yahoo 
回复:JADE 3.3的bug
回复:JADE 3.3的bug
回复:JADE 3.3的bug
回复:JADE 3.3的bug
回复:Jbpm和Shark比较的feat
回复:JADE 3.3的bug
回复:JADE 3.3的bug
回复:[转]批判性地看待一种可行的表示技
回复:JIRA破解


The Fishkeeper
blog名称:SW Portal
日志总数:171
评论数量:219
留言数量:8
访问次数:1050869
建立时间:2004年10月30日



Text Me

.: 留言板

签写新留言

路过
路过
页脚问题
RE:请问一下你的主页的下面部分是怎么关
请问一下你的主页的下面部分是怎么关闭的?
我是做Mobile Agent的
Gmail
不错
不错啊小倪同学


Other Fish in the Sea

.: 链接





站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144791146 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号