aspx語法比較簡單,所以aspx解析器幾乎完全是通過正規表示式來實現的。razor解析器與aspx解析器之間有很大不同,它實際上分為三個獨立的元件:
1)理解基礎html語法的標記解析器;
2)理解基礎c#或者vb語法的**解析器;
3)理解標記和**如何混合的**控制器
所以razor解析器有三個參與者:**解析器,標記解析器,**解析器。三個元件相互配合,協同工作完成對razor文件的解析。razor解析器有三種狀態,分別是:解析標記文件、解析標記塊,解析**塊,任何情況下解析器都處在以上三種狀態中的一種狀態上。前兩種狀態由標記解析器來處理,最後一種狀態由**解析器處理。
在此我們依然使用上次的例子來說明使用這些元件解析razor文件的過程。
檔案內容如下:
我們從最上面開始解析過程。當第一次呼叫核心解析器的時候,它會呼叫標記解析器來解析標記文件。此時,解析器處在解析標記文件狀態,在這種狀態下,它會一直向前掃瞄,直到找到下乙個"@"字元,除此之外它不關心任何標記或者其它html相關的內容。當遇到乙個"@"字元的時候,它會通過檢視"@"字元前後的內容,並據此判斷是切換到**狀態呢還是這僅僅是乙個email位址。這是預設的處理方式,但是有些特殊情況會強制解析器切換到**解析狀態。本例中,當解析到"@"字元的時候,會發現該字元的前面是空格,據此判定這並不是乙個合法的email位址,所以切換到**解析狀態。標記解析器接著呼叫**解析器,讓其來解析**塊。在razor中塊為單獨的一段**或者是有明確開始結束字串行的標記,因而此處的"foreach"宣告是**塊,它以字元"f"開始,以字元"}"結束。**解析器非常清楚c#語法,他會跟蹤c#指令,當遇到""字串行的時候,它知道此處應該是c#指令的開始,但c#並不支援這樣的指令,因而**解析器會再次呼叫標記解析器來解析接下來的html**塊。這樣在**和標記解析器之間建立一種從標記解析開始,進入**解析,然後再進入標記解析….的遞迴過程。到目前為止,解析器內的呼叫棧應該類似於以下結構(省略了一些幫助方法):
htmlmarkupparser.parsedocument()我們可以從中看出aspx和razor的區別:在aspx檔案中,**和標記可以看作是兩個並行的流,我們寫一些標記然後跳過去寫一些**,再跳回來寫標記,如此進行;而razor檔案更像是一棵樹,我們寫一些標記,然後在標記裡面寫一些**,再在**中嵌入標記….。csharpcodeparser.parseblock()
htmlmarkupparser.parseblock()
所以我們僅需要呼叫標記解析器去解析""和""之間的標記塊,在沒有到達""之前解析器認為標記塊還沒結束,哪怕在標記之間有"}"字元都不會打斷"foreach"宣告。
當解析""的時候,標記解析器發現了"@"字元,因而**解析器會被呼叫,此時棧結構變成:
htmlmarkupparser.parsedocument()對於這些**塊如何終止的具體資訊以後再做介紹,但是最終我們會完成這些**塊的解析並且回到""塊中,在""之後又回到了"foreach"塊中,最後"}"字元結束了"foreach"塊,重新回到棧的頂端:標記文件。之後因為沒發現新的"@"字元,文件解析器將一直解析到檔案的結尾。csharpcodeparser.parseblock()
htmlmarkupparser.parseblock()
csharpcodeparser.parseblock()
檢視英文原文
譯 Razor內幕之解析
aspx語法比較簡單,所以aspx解析器幾乎完全是通過正規表示式來實現的。razor解析器與aspx解析器之間有很大不同,它實際上分為三個獨立的元件 1 理解基礎html語法的標記解析器 2 理解基礎c 或者vb語法的 解析器 3 理解標記和 如何混合的 控制器 所以razor解析器有三個參與者 解...
譯 Razor內幕之介紹
razor語法的主要設計目標是 讓 和標記流能夠一起工作同時盡量不與控制字元衝突。例如,下面的aspx 現在,我們僅留下我們實際上關注的東西,去除額外的aspx控制字元,處理後的 如下 很顯然,上面的 中並沒有足夠的資訊來決定那些是 那些是標記。razor引擎在設計的時候希望加入盡量少的資訊來分辨上...
Java Web技術內幕筆記 DNS解析
當乙個使用者在瀏覽器輸入 時,dns 解析將會有近 10 個步驟,這個過程大致描述如下。當使用者在瀏覽器輸入網域名稱並按下回車之後,第 1 步,瀏覽器會檢查快取中有沒有這個網域名稱對應的解析過的 ip 位址,如果快取中有,這個解析過程就將結束。瀏覽器快取網域名稱也是有限制的,不僅瀏覽器快取大小有限制...