[譯]EPUB Canonical Fragment Identifier (epubcfi) Specificationhtml
[注]因爲做者本文水平有限,加之英文理解有限,本文翻譯旨在學習EPUB CFI規範,經過本文看快速瞭解CFI標記方法和理解CFI在EPUB出版物中的做用。git
EPUB CFI規範經過在EPUB出版物中使用片斷標識定義引用到任意內容的標準化方法。架構
網頁已經證實了超連接的概念是及其強大的,然而,EPUB出版物已經否認了超連接可能帶來的好處,應爲它缺少一個連接到內容的標準機制。儘管一些私有化的機制已經被一些閱讀系統開發並實現,然而他們沒有一個好理解的語法,而且沒有達到跨平臺的互操做性。打破互操做性障礙從功能性來看是意義重大的,而且,該規範作出一些改變:從閱讀位置維護一個標註用於導航,並指向任何出版物的能力打開了一個新的維度,不只僅像超連接那樣只有做者或開發人員才能夠添加。app
EPUB CFI規範定義一個能惟一識別在出版物中的任何位置或簡單範圍的結構化引用試圖糾正目前的狀態。下面一些考慮強烈的影響了該規範的設計和範圍:ide
在文檔中使用的EPUB規範術語請參考EPUB規範。svg
出版級別的EPUB CFI連接到一個EPUB出版物。EPUB CFI的路徑引用到出版物的位置。函數
一個內部的EPUB CFI出版物容許一個內容文檔引用到出版物內部另一個文檔。這個EPUB CFI路徑引用到當前出版物文檔包。學習
詳情請參考內部出版物的CFI。測試
片斷標識符是IRI[RFC3987]規範的一部分,定義了資源中的位置。語義上,它是一個以井號(#)開始並附到IRI資源尾部的片斷。對HTML文檔而言,ID和命名的錨被做爲片斷標識符,在XML中,縮寫的的XPointer[XPTRSH]標識被用來引用到給定的ID。flex
標準片斷標識符(CFI)是一個相似的結構,它用來表示一個EPUB出版物中的一個位置信息。例如:
book.epub#epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/3:10)
跟在井號(#)後面的函數式字符串表示了符合本文檔規範的片斷標識符,而且,包含在括號中的值是一個用於引用到規範出版物(book.epub)中的一個片斷位置。使用在路徑解析一節中定義的處理規則,任何閱讀系統能夠解析這些語法,打開對應出版物的內容文檔,併爲用戶定位到指定位置。
一個完整的EPUB CFI語法定義在下一節中闡述。
(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^]])
在路徑和範圍中,對數字和整數使用時應知足如下規則:
2.3 字符轉義
(略)
斜線(/)後跟一個整數的步驟如下面的方式引用到一個或多個子節點:
[譯註:]對於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開始的根元素的引用位置的節點編號。
當EPUB CFI引用到一個包含ID的元素是,相應的路徑步驟必須在方括號中包含該ID(例如,在斜線和指示元素的偶數後面)。
標識符規範增長量CFI架構的魯棒性:閱讀系統能夠確認CFI指向的位置是否有原來想要的位置,而且,可使用這個標識符計算一些到達指望目標位置的步驟(參見有意目標位置校訂)。增長魯棒性所產生的反作用是對CFI字符串比較(排序)可能須要跳過全部中括號後才能夠執行(參見排序規則)。
一個以感嘆號(!)開始的步驟指示後面的引用必須被跟蹤,並引用到新的目標節點(或引用的一個完整的XML文檔的根元素)。
僅下面的引用被接受:
注意:這個規範沒有考慮超連接,僅僅考慮了嵌入式引用,所以,跟蹤一個HTML5或SVG中的a元素是無效的。
帶冒號的終止步驟,跟一個整數表示一個字符偏移。字符偏移能夠應用到一個HTML5中的img元素節點,並且該節點必須包含一個alt屬性,其中的字符偏移被引用。
對於文本節點,偏移是從零開始的,而且老是指向字符間的位置,因此0意味着第一個字符的前面,一個等於UTF-16總長度的數表示最後一個字符。不能指定大於可用文本的UTF-16最大長度的字符偏移值。
一個字符偏移終止步驟能夠呈現爲/N的步驟。對於XML內容文檔,但參考img的alt文本時,N應該是一個偶數;引用普通文本節點時,N應該是一個奇數。
字符偏移終止步驟後面不能有其餘步驟。
以波浪符號(~)開始跟一個數字的終止步驟表示音頻或視頻的時間偏移,單位爲秒。
時間偏移終止步驟後面不能有其餘步驟。
以@符號開頭更兩個冒號分隔數字的終止步驟表示一個圖片或視屏中二維(2D)空間位置。這兩個數字表示x和y座標的縮放比例位置,而且,不管視頻或圖片的顯示維度,該值得範圍始終是0~100之間(例如:0:0表示左上角,100:100表示右下角)。
空間偏移終止步驟後面不能有其餘步驟。
時間和空間位置能夠一塊兒使用。這種狀況下,語義上,時間規範必須在空間規範以前(例如:~23.5@5.75:97.6引用到視頻的23.5秒靠左下的邊框位置)。
時間偏移終止步驟後面不能有其餘步驟。
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字符串時可能須要跳過全部以中括號包括的字符串(參見排序規則)。
在一些狀況下,保留引用指向位置的邊界是重要的。例如,在一個動態分頁的環境中當解析一個位置時,位置表示指向以前仍是以後的內容是有些不一樣的(例如,在分頁位置上的引用,決定顯示左邊仍是右邊的頁面時就須要考慮邊界偏好)。
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比較而言,它沒有特殊須要處理的。
邊界對於空間邊界沒有定義。
注意:邊界偏好僅在一些分隔符位置纔有意義(例如:分頁符或換行符)
給定一個下列文檔包:
<?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)
爲計算或排序引用到同一出版物的多個EPUB CFI的相對位置時,下列規則必須應用:
內部出版物能夠在容器內引用。這類引用可以指定一個引用到文檔包的CFI來歸檔,這個CFI必須從跟節點開始解析。
例如,使用在前面示例的文檔包,在第二章(chapter02.xhtml)中引用到上例中最後一個示例的位置能夠表示以下:
<a href="../pub.opf#epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[;s=b])">location</a>
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的排序而言,若是不查詢文檔內容將是不可能完成的。
假如範圍使用在上下文期待的單個位置,開始位置必須使用。
邊界偏好參數不能在範圍中使用,範圍的開始暗示開始位置以後的內容,結束暗示着結束位置以前的內容。
正如一個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。
提供擴展(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 .