EPUB CFI 规范

EPUB CFI 规范

[译]EPUB Canonical Fragment Identifier (epubcfi) Specification

[注]由于作者本文水平有限,加之英文理解有限,本文翻译旨在学习EPUB CFI规范,通过本文看快速了解CFI标记方法和理解CFI在EPUB出版物中的作用。

一、综述

1.1 意图和范围

EPUB CFI规范通过在EPUB出版物中使用片段标识定义引用到任意内容的标准化方法。

网页已经证明了超链接的概念是及其强大的,然而,EPUB出版物已经否定了超链接可能带来的好处,应为它缺乏一个链接到内容的标准机制。尽管一些私有化的机制已经被一些阅读系统开发并实现,然而他们没有一个好理解的语法,并且没有达到跨平台的互操作性。打破互操作性障碍从功能性来看是意义重大的,并且,该规范做出一些改变:从阅读位置维护一个标注用于导航,并指向任何出版物的能力打开了一个新的维度,不仅仅像超链接那样只有作者或开发人员才可以添加。

EPUB CFI规范定义一个能唯一识别在出版物中的任何位置或简单范围的结构化引用试图纠正目前的状态。下面一些考虑强烈的影响了该规范的设计和范围:

  • 引用内容的机制应该具有互操作性:在一个阅读系统中创建的位置引用应该可以在其它阅读器中同样可以使用。
  • 引用到EPUB内容的文档应该与在WEB中通过超链接方式引用具有相同的方式。
  • 在EPUB文件中的每一个位置应该可以定位而不需要修改文档。
  • 所有引用到相同位置的片段标识符在比较是应该是相等的。
  • 比较操作,包括排序或比较测试,应可以在不需要访问参考文件的情况下执行。
  • 简单操作应尽可能的不需要访问原文件(例如:给定指向一个文件内容的引用,应该可以生成一个到文件开始的引用)
  • 标识符解析应该合理的高效(例如:处理第一章时不需要解析最后一章的片段标识符)
  • 引用应该在解析器变化或文档修订后可以恢复他们的目标位置。
  • 支持简单表达式和连续范围
  • 应提供一个适应将来引用恢复方法扩展机制

1.2 术语

在文档中使用的EPUB规范术语请参考EPUB规范。

  • 标准EPUB CFI

出版级别的EPUB CFI链接到一个EPUB出版物。EPUB CFI的路径引用到出版物的位置。

  • 内部EPUB CFI

一个内部的EPUB CFI出版物允许一个内容文档引用到出版物内部另外一个文档。这个EPUB CFI路径引用到当前出版物文档包。

详情请参考内部出版物的CFI。

二、EPUB CFI定义

2.1 简介

片段标识符是IRI[RFC3987]规范的一部分,定义了资源中的位置。语义上,它是一个以井号(#)开始并附到IRI资源尾部的片段。对HTML文档而言,ID和命名的锚被作为片段标识符,在XML中,缩写的的XPointer[XPTRSH]标识被用来引用到给定的ID。

标准片段标识符(CFI)是一个类似的结构,它用来表示一个EPUB出版物中的一个位置信息。例如:

book.epub#epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/3:10)

跟在井号(#)后面的函数式字符串表示了符合本文档规范的片段标识符,并且,包含在括号中的值是一个用于引用到规范出版物(book.epub)中的一个片段位置。使用在路径解析一节中定义的处理规则,任何阅读系统可以解析这些语法,打开对应出版物的内容文档,并为用户定位到指定位置。

一个完整的EPUB CFI语法定义在下一节中阐述。

2.2 语法

(EBNF productions ISO/IEC 14977)

fragment	=	 "epubcfi(" , ( path | range ) , ")" ;	 
path	=	step , local_path ;	 
range	=	path , "," , local_path , "," , local_path ;	 
local_path	=	 { step | "!" } , [ termstep ] ;	 
step	=	 "/" , integer , [ "[" , assertion , "]" ] ;	 
termstep	=	terminus , [ "[" , assertion , "]" ] ;	 
terminus	=	 ( ":" , integer ) | ( "@" , number , ":" , number ) | ( "~" , number ) | ( "~" , number , "@" , number , ":" , number ) ;	 
number	=	 ( digit-non-zero , { digit } , [ "." , { digit } , digit-non-zero ] ) | ( zero , "." , { digit } , digit-non-zero ) ;	 
integer	=	zero | ( digit-non-zero , { digit } ) ;	 
assertion	=	 [ csv ] , { parameter } ;	 
parameter	=	 ";" , value-no-space , "=" , csv ;	 
csv	=	value , { "," , value } ;	 
value	=	string-escaped-special-chars ;	 
value-no-space	=	value - ( [ value ] , space , [ value ] ) ;	 
special-chars	=	circumflex | square-brackets | parentheses | comma | semicolon | equal ;	 
escaped-special-chars	=	 ( circumflex , circumflex ) | ( circumflex , square-brackets ) | ( circumflex , parentheses ) | ( circumflex , comma ) | ( circumflex , semicolon ) | ( circumflex , equal ) ;	 
character-escaped-special	=	 ( character - special-chars ) | escaped-special-chars ;	 
string-escaped-special-chars	=	character-escaped-special , { character-escaped-special } ;	 
string	=	character , { character } ;	 
digit	=	zero | digit-non-zero ;	 
digit-non-zero	=	 "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;	 
zero	=	 "0" ;	 
space	=	 " " ;	 
circumflex	=	 "^" ;	 
double-quote	=	 '"' ;	 
square-brackets	=	 "[" | "]" ;	 
parentheses	=	 "(" | ")" ;	 
comma	=	 "," ;	 
semicolon	=	 ";" ;	 
equal	=	 "=" ;	 
character	=	 ? Unicode Characters ? ;

Unicode字符

CFI定义中允许的Unicode字符与[XML 1.0]定义一样。下面为一些排除的代理块(Unicode术语)以及0xFFFE和0xFFFF:

#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

文档中应该少用“兼容字符集”,如定义在Unicode规范2.3节的那些。下面定义的字符集范围一样不推荐。它们要么是控制字符,要么是永不定义的Unicode字符:

[#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDEF],
[#x1FFFE-#x1FFFF], [#x2FFFE-#x2FFFF], [#x3FFFE-#x3FFFF],
[#x4FFFE-#x4FFFF], [#x5FFFE-#x5FFFF], [#x6FFFE-#x6FFFF],
[#x7FFFE-#x7FFFF], [#x8FFFE-#x8FFFF], [#x9FFFE-#x9FFFF],
[#xAFFFE-#xAFFFF], [#xBFFFE-#xBFFFF], [#xCFFFE-#xCFFFF],
[#xDFFFE-#xDFFFF], [#xEFFFE-#xEFFFF], [#xFFFFE-#xFFFFF],
[#x10FFFE-#x10FFFF].


CFI由一个以epubcfi字符开始和一个以括号括起来的路径或范围构成。epubcfi指示一个特殊的引用方法。路径构建了一个引用到特定位置的结构化有序步骤。范围是一条表示开始和结束范围位置的两个本地(或相对)路径。

步骤要么是导航步骤,要么是终止步骤。导航步骤可以重复多次(例如:计数元素,处理子节点,或跟随引用)。终止步骤只能是唯一,如果有,必须是最后一个步骤。

在括号中的字符串可以是可扩展的断言:用于提高路径遍历和文档修订过程中的鲁棒性。断言保留遍历文档元素的额外信息,它为出版物在做一些修订后恢复想要的位置提供了一种可能。

尽管前面语法描述中value的定义允许任何字符,但是,抑扬符号(^)必须用来转义下列字符,以确保它们的存在不会影响语义转换:

  • 中括号( [,] )
  • 抑扬符号( ^ )
  • 逗号( , )
  • 圆括号( (,) )
  • 分号( ; )

例如指向文本2[1]位置的EPUB CFI需要使用转义符:

epubcfi(/6/7[chap05ref]!/4[body01]/10/2/1:3[2^[1^]])

在路径和范围中,对数字和整数使用时应满足以下规则:

  • 数值和整数中不允许前导零,以确保唯一性
  • 数值小数部分中不允许后导零
  •  0只允许表示0
  •  在0到1间的小数,必须要有前导零,如0.1
  •  积分数字必须表示为整数

2.3 字符转义

(略)

三、EPUB CFI处理过程

3.1 路径解析

3.1.1 引用到子节点的步骤(/)

斜线(/)后跟一个整数的步骤以下面的方式引用到一个或多个子节点:

  • 每一个元素赋予一个正偶数,第一个元素为2,第二个为4,以此类推
  • 每一个非元素节点的集合(可能为空)赋予一个奇数的序号,以表示他们在文档中的位置(他们典型的表示出版物的文本)。非元素节点集合包括第一个元素前,两个元素间,最后一个元素后面的所有内容的
  • 非文本节点的非元素节点总是忽略(对于本规范,文本节点包括文本,CDATA和实体引用)这个索引的方法确保节点标识对XML解析器处理空白文本,CDATA节和实体引用是不敏感的。(例如可以避免产生以下依赖,一个XML解析器是否折叠只有空格的文本节点,或保持文本,CDATA节或实体引用作为独立的节点,或打断在多个节点中的文本)。

[译注:]对于3.1.10示例文档而言,epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy])的完整表示为:epubcfi表示规范,/6表示文档包中的第三个元素(偶数计数),即spine元素,/4[chap01ref]! 其中,/4表示spine的第二个子元素itemref,id为chap01ref表示为[chap01ref],后面的感叹号表示需要间接解析,即访问idref属性:chapter01,该元素在文档包中manifest定义,引用“chapter01.xhtml"文件,后面的步骤为该文件的解析,/4[body01]表示第二个元素,body元素,具有id="body01",ID必须出现;接着,/10[para05]表示body的第五个子元素p, 有id="para05", 接着是/2表示p元素的第一个子元素em;接着,/1:3[yyy]为最后一个元素--终止元素,/1表示第一个非元素的文本,:3表示字符偏移,[yyy]表示便宜位置前的断言,断言第三个字符后(序号基于0)位置上前面为yyy字符。

这个索引的方法确保节点标识对XML解析器处理空白文本,CDATA节和实体引用是不敏感的。(例如可以避免产生以下依赖,一个XML解析器是否折叠只有空格的文本节点,或保持文本,CDATA节或实体引用作为独立的节点,或打断在多个节点中的文本)。

对于标准EPUB CFI ,前导CFI必须以斜线(/)开始,后面跟一个表示在包文档根元素package下的spine子节点的引用位置的偶数。被CFI遍历的包文档必须在出版物的META-INFO/container.xml文件中指定为缺省文档(例如,包文档通过container.xml文件中的第一个rootfile元素定义)。

对于内部EPUB CFI,第一个步骤必须用斜线(/)开始,跟一个引用到以package开始的根元素的引用位置的节点编号。

3.1.2 XML ID断言( [ )

当EPUB CFI引用到一个包含ID的元素是,相应的路径步骤必须在方括号中包含该ID(例如,在斜线和指示元素的偶数后面)。

标识符规范增加量CFI架构的鲁棒性:阅读系统可以确认CFI指向的位置是否有原来想要的位置,并且,可以使用这个标识符计算一些到达期望目标位置的步骤(参见有意目标位置校正)。增加鲁棒性所产生的副作用是对CFI字符串比较(排序)可能需要跳过所有中括号后才可以执行(参见排序规则)。

3.1.3 间接步骤

一个以感叹号(!)开始的步骤指示后面的引用必须被跟踪,并引用到新的目标节点(或引用的一个完整的XML文档的根元素)。

仅下面的引用被接受:

  • 对于文档包中的spine元素的itemref属性,引用由manifest元素的item子节点href属性定义(例如,itemref的idref属性引用)
  • 对于HTML5的iframe或embed元素,引用由src属性定义
  • 对于HTML的object元素,引用有data属性定义
  • 对于SVG的image和use元素,引用有xlink:href属性定义

注意:这个规范没有考虑超链接,仅仅考虑了嵌入式引用,因此,跟踪一个HTML5或SVG中的a元素是无效的。

3.1.4 终止步骤-字符偏移( : )

带冒号的终止步骤,跟一个整数表示一个字符偏移。字符偏移可以应用到一个HTML5中的img元素节点,而且该节点必须包含一个alt属性,其中的字符偏移被引用。

对于文本节点,偏移是从零开始的,并且总是指向字符间的位置,所以0意味着第一个字符的前面,一个等于UTF-16总长度的数表示最后一个字符。不能指定大于可用文本的UTF-16最大长度的字符偏移值。

一个字符偏移终止步骤可以呈现为/N的步骤。对于XML内容文档,但参考img的alt文本时,N应该是一个偶数;引用普通文本节点时,N应该是一个奇数。

字符偏移终止步骤后面不能有其他步骤。

3.1.5 终止步骤-时间偏移 (~)

以波浪符号(~)开始跟一个数字的终止步骤表示音频或视频的时间偏移,单位为秒。

时间偏移终止步骤后面不能有其他步骤。

3.1.6 终止步骤-空间偏移 (@)

以@符号开头更两个冒号分隔数字的终止步骤表示一个图片或视屏中二维(2D)空间位置。这两个数字表示x和y坐标的缩放比例位置,并且,无论视频或图片的显示维度,该值得范围始终是0~100之间(例如:0:0表示左上角,100:100表示右下角)。

空间偏移终止步骤后面不能有其他步骤。

3.1.7 终止步骤-时空偏移(~ + @)

时间和空间位置可以一起使用。这种情况下,语义上,时间规范必须在空间规范之前(例如:~23.5@5.75:97.6引用到视频的23.5秒靠左下的边框位置)。

时间偏移终止步骤后面不能有其他步骤。

3.1.8 文本位置断言 ( [ )

EPUB CFI可以在设定的位置上指定前面或后面跟随的字符的断言,并且这些断言必须出现在字符偏移终止步骤之后。

例如:下列表达式断言”yyy”在指定位置的之前出现(使用下面的示例内容)

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy])

在一个冒号后面的一个额外的子串可以断言指定位置点后面出现。例如:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/1:3[xx,y])

通过星号标记引用指向的位置:

x x x y y y 0 1 2 3 4 5 6 7 8 9
| | | * | | | | | | | | | | | |

如果没有指定前面的文本,或者只有后面的文本被指定,一个冒号必须必须在文本断言之前出现,例如:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[,y])

对断言匹配可以包含的作为前导或后随的文本数量没有限制。文本取至文档,忽略元素边界,并且空格总是被压缩(例如,非空序列连续的空格总是被一个空格所代替)。

阅读系统可以通过CFI确定引用的位置是否是原始想要的位置(由于比匹配的文本),并且可以使用前导后后随文本去计算期望达到的位置(参见有意目标位置校正)。添加鲁棒性的副作用是比较(排序)CFI字符串时可能需要跳过所有以中括号包括的字符串(参见排序规则)。

3.1.9 边界偏好([ + ; s=)

在一些情况下,保留引用指向位置的边界是重要的。例如,在一个动态分页的环境中当解析一个位置时,位置表示指向之前还是之后的内容是有些不同的(例如,在分页位置上的引用,决定显示左边还是右边的页面时就需要考虑边界偏好)。

s参数用于保留引用位置的边界观点,它具有liangge 值:b表示引用位置之前的内容,而a表示之后的内容。这个参数必须在CFI的最后一个步骤中使用,并只能在方括号中使用,即使XML的ID或断言文本为空也可以使用。

在下面示例内容中yyy后面的位置可以通过边界偏好表示为属于该引用之前的内容:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[;s=b])

同样,他可以表达在一个文本断言后面:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy;s=b])

表示em元素开始之前的位置可以用如下方式表示:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2[;s=b])

如果前面的例子中,把b设置成a,那么所表示的位置是em元素的子内容,而不是em元素后面的内容。

由于边界偏好表达为一个参数,对CFI比较而言,它没有特殊需要处理的。

边界对于空间边界没有定义。

注意:边界偏好仅在一些分隔符位置才有意义(例如:分页符或换行符)

3.1.10 示例

给定一个下列文档包:

<?xml version="1.0"?>

<package version="2.0" 
         unique-identifier="bookid" 
         xmlns="http://www.idpf.org/2007/opf"
         xmlns:dc="http://purl.org/dc/elements/1.1/" 
         xmlns:opf="http://www.idpf.org/2007/opf">
    
    <metadata>
        <dc:title>...</dc:title>
        <dc:identifier id="bookid">...</dc:identifier>
        <dc:creator>...</dc:creator>
        <dc:language>en</dc:language>
    </metadata>
    
    <manifest>
        <item id="toc"
              properties="nav"
              href="toc.xhtml" 
              media-type="application/xhtml+xml"/>
        <item id="titlepage" 
              href="titlepage.xhtml" 
              media-type="application/xhtml+xml"/>
        <item id="chapter01" 
              href="chapter01.xhtml" 
              media-type="application/xhtml+xml"/>
        <item id="chapter02" 
              href="chapter02.xhtml" 
              media-type="application/xhtml+xml"/>
        <item id="chapter03" 
              href="chapter03.xhtml" 
              media-type="application/xhtml+xml"/>
        <item id="chapter04" 
              href="chapter04.xhtml" 
              media-type="application/xhtml+xml"/>
    </manifest>
    
    <spine>
        <itemref id="titleref"  idref="titlepage"/>
        <itemref id="chap01ref" idref="chapter01"/>
        <itemref id="chap02ref" idref="chapter02"/>
        <itemref id="chap03ref" idref="chapter03"/>
        <itemref id="chap04ref" idref="chapter04"/>
    </spine>
    
</package>

和XHTML内容文档chapter01.xhtml

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>...</title>
    </head>
    
    <body id="body01">
        <p>...</p>
        <p>...</p>
        <p>...</p>
        <p>...</p>
        <p id="para05">xxx<em>yyy</em>0123456789</p>
        <p>...</p>
        <p>...</p>
        <img id="svgimg" src="foo.svg" alt="..."/>
        <p>...</p>
        <p>...</p>
    </body>
</html>

如EPUB CFI:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/3:10)

引用到ID为para05的段落中数字9的后面位置。

当需要为文本位置生成一个CFI是,除非文本由img元素的alt属性定义,文本位置应该总是开始于文本节点或文本节点集合(即使为空),并计数到相应的位置,让后一直跟踪它的祖先一直到文档包的根节点。

下面例子显示EPUB CFI如何构造一些内容位置的引用:

引用到img元素:

epubcfi(/6/4[chap01ref]!/4[body01]/16[svgimg])

引用到xxx位置之前:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/1:0)

引用到yyy位置之前:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:0)

引用到yyy位置之后:

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)

3.2 排序规则

为计算或排序引用到同一出版物的多个EPUB CFI的相对位置时,下列规则必须应用:

  1. EPUB CFI模式数据必须使用非转义的形式,如前面在字符转义一节描述的规则一样
  2. 所有括号中的断言整体移除或忽略
  3. 在步骤序列中,越前面越重要
  4. XML子节点,字符偏移和时间偏移以自然顺序排序
  5. y坐标位置比x坐标更重要
  6. 在其他空间偏移之前省略空间偏移
  7. 在其他时间便宜之前省略时间偏移
  8. 时间偏移比空间偏移更重要
  9. 不同的步骤类型以不重要到重要顺序排列:字符偏移(:),子节点(/),时间-空间偏移(~或@),引用或间接(!)

3.3 内部出版物的CFI

内部出版物可以在容器内引用。这类引用能够指定一个引用到文档包的CFI来归档,这个CFI必须从跟节点开始解析。

例如,使用在前面示例的文档包,在第二章(chapter02.xhtml)中引用到上例中最后一个示例的位置可以表示如下:

<a href="../pub.opf#epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[;s=b])">location</a>

3.4 简单范围

EPUB CFI允许扩展开始到结束位置的简单范围表达式。一个范围表达式必须表达为一个三元组:父路径,开始子路径,结束子路径,或以下形式:

epubcfi(P,S,E)

父路径必须停止在开始和结束位置范围路径的共同部分,并且,开始和结束子路径必须以非增加的顺序解析到文档位置。

为确定范围开始和结束的位置,开始和结束子路径必须可以连接到父路径以创建开始位置路径(PS)和结束路径(PE)。

使用前面的示例文档,下面的范围描述了从yyy中的第二个yzifu 到数字3(包含3):

epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)

范围必须依照PS然后再PE来比较。

使用一个指向元素的路径来代替元素的开始和结束位置是无效的。单个路径表示法总是标注一个位置,并且,范围由上面描述的表示法表示。这里没有一个可以产生指向元素结尾的特殊的步骤,如果有,那么对CFI的排序而言,如果不查询文档内容将是不可能完成的。

假如范围使用在上下文期待的单个位置,开始位置必须使用。

边界偏好参数不能在范围中使用,范围的开始暗示开始位置之后的内容,结束暗示着结束位置之前的内容。

3.5 目标位置校正

正如一个EPUB出版物可能随着时间的推移,需要更新,校正或修改,能够从前一个版本的标注为修改后的文档推断一个EPUB CFI是有用的。本规范提供了两种机制去检测或适应内容改变对CFI的影响:XML中的ID和文本位置断言。

当一个阅读系统在处理CFI时,它应该检查任何遇到断言的正确性。例如,给定路径/6/4[chap01ref]!...,阅读系统应该在处理原素4时验证元素的ID是否匹配chap01ref(对于本例,在spine中的itemref属性)。如果不匹配,阅读器应该定位在文档中的chap01ref,并校正CFI(例如,如果一个新的itemref插入在chap01ref的itemref前面,这样,实际期望的元素序号现在变成了6,并且校正的CFI应该为/6/6[chap01ref]!...)。同样,文本位置断言应该用于检查引用的目标位置,并使用它为期待的文本位置推断校正后的CFI。

如果在处理过程中,有一个断言失败,一个校正的CFI也不能推断(ID在文档中没有找到,或匹配的文本没有找到),CFI必须认为这是一个无效引用。在阅读器不能检查其正确性的情况下(例如,在CFI处理阶段驻留文档的XML ID不可用时),它必须忽略CFI断言。

校正CFI的概念会导致两个不同的CFI指向同一位置的情况(例如,老的CFI,准备校正的和已经校正的)。校正后的CFI应该在可能的情况下使用。阅读器和任何围绕内容管理的系统应该试图在可能的情况下用校正好的版本替换陈旧的CFI。

注意:本规范鼓励自定义功能开发辅助CFI校正,目前在校正上的功能是不够的。更多开发这些功能的信息参考扩展EPUB CFI

4 扩展EPUB CFI

提供扩展(CSV参数列表,参数名前缀,并且用分号分开)允许阅读器应用新的或启发性的实验去辅助迁移EPUB CFI片段以更新文档。

强烈建议任何厂商规范名称以vnd开始,后面跟厂商名称。

所有实现必须忽略所有不能理解或不能转换的参数。

参考:

正式参考
[EPUBCFI] EPUB Canonical Fragment Identifier (epubcfi) Specification .
[HTML5] HTML5: A vocabulary and associated APIs for HTML and XHTML . 
[RFC2119] Key words for use in RFCs to Indicate Requirement Levels (RFC 2119) . March 1997. 
[RFC2279] UTF-8, a transformation format of ISO 10646 (RFC 2279) . F. Yergeau, et al. January 1998. 
[RFC2396] Uniform Resource Identifiers (URI): Generic Syntax (RFC 2396) . T. Berners-Lee, et al. August 1998. 
[RFC2732] Format for Literal IPv6 Addresses in URL's (RFC 2732) . R. Hinden, et al. December 1999.
[RFC3986] Uniform Resource Identifier (URI): Generic Syntax (RFC 3986) . Berners-Lee, et al. January 2005.
[RFC3987] Internationalized Resource Identifiers (IRIs) (RFC 3987) . M Duerst, et al. January 2005.
[SVG] Scalable Vector Graphics (SVG) 1.1 (Second Edition) . Erik Dahlström, et al. 09 June 2011.
[XML] Extensible Markup Language (XML) 1.0 (Fifth Edition) . T. Bray, et al. 26 November 2008.
非正式参考
[XPTRSH] XPointer Shorthand Notation .


原文地址:https://www.cnblogs.com/yin138/p/4902245.html