2010-05-29 40 views
0

我錯過了一些相當簡單的語法,我收集。我試圖重寫一個元素標籤到其他東西,並保持一切完好無損。scala xml重寫規則(或簡單模式幫助)

object htmlRule extends RewriteRule { 
override def transform(n: Node): Seq[Node] = n match { 
    case Elem(prefix, "document", attribs, scope, [email protected]_*) => 
    Elem(prefix, "html", attribs, scope, child) 
    case other => other 
} 
} 

現在,我問了兩件事情的解釋:

1)究竟做 「孩@ _ *」 的意思是用簡單的英語?

2)如何捕獲「child @ _ *」的值並讓它直接傳遞給新元素?目前,我收到以下錯誤,這是有道理的。

[error] found : Seq[scala.xml.Node] 
[error] required: scala.xml.Node 
[error]  Elem(prefix, "html", attribs, scope, child) 

我不會執着於這兩種,所以如果有一個更好的方式來簡單地改變一個特定節點的元素名稱,讓我們來這裏吧......

感謝, --tim

回答

5

記號:

case ... bindVar @ patternConstraint ... => /* bindVar is bound to what patternConstraint matched here */ 

允許以匹配「之內」的值(在patternConstraint部分),同時捕獲經受約束的整體價值(如bindVa R)。

你的具體情況,child @ _*,在_表示「不關心」,在*意味着值的順序和child @意味着綁定孩子的整個序列。

甲頻繁使用這種能力的是嵌套圖案(通常是提case類):

case expr @ Expr(op, lhs, rhs) => // Do stuff with expr, op, lhs and rhs 

在此,匹配的目標被測試以看是否它是Expr一個實例,並且如果它是,op綁定到Expr的運營商,lhsrhs綁定到它的左側和右側,並且expr被綁定到Expr實例本身。

+0

感謝Randall, 你可以解釋它與一個Elem與一個節點序列_ *相匹配的奇怪現象嗎?但是,Elem構造函數不需要一個節點序列?首先,這是正確的嗎?其次,如果是這樣,那麼達到我想要的行爲的方式是什麼?感謝您詳細的綁定說明:) – Tim 2010-05-29 15:04:12

+1

使用子代:_ *將Seq [Node]作爲Node * vararg參數應用。 – 2010-05-29 16:27:07

+0

謝謝西爾維奧,我仍然不確定爲什麼這個神奇的語法工作,但它確實。很顯然,我有一個全新的Scala學習領域:) – Tim 2010-05-29 17:04:20

1

Elem不是一個案例類,它是一個帶有伴隨對象的「普通」類。有一種方法可以編寫普通(非大小寫)的類來模擬案例類。但更典型的情況是將案例類視爲編寫大量樣板代碼的簡寫,其中一些在類中,另一些在隱式創建的同伴中。在這種情況下,相關位是伴隨對象中的unapply和/或unapplySeq方法。這些方法是使非案例類適用於模式匹配的原因。

對於Elem相關匹配的「簽名」是的object scala.xml.Elem#unapplySeq(...),具體是:

def unapplySeq(n: Node): Option[(String, String, MetaData, NamespaceBinding, Seq[Node])] 

在那裏你可以看到Elem匹配時創建綁定的模式。它們實際上對應於您在示例代碼中使用的模式。