开发者

scala xml rewrite rule (or, simple pattern help)

I'm missing some fairly simple syntax I gather. I'm trying to rewrite an element label to something else and keep everything else intact.

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

Now, I ask for an explanation of two things:

1) What exactly does "child@_*" mean in plain English?

2) How can I capture the value of "child@_*" and just let it pass right through to the new element? Currently, I get the following error, which makes sense.

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

I'm not wedded to this either, so if there's a better way to simply change the element name of a specific node, let's here it...

开发者_Python百科

Thanks, --tim


The notation:

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

Allows you to match "within" a value (the patternConstraint part) while capturing the overall value subjected to that constraint (as bindVar).

In your particular case, child @ _*, the _ means "don't care", the * means a sequence of values and child @ means bind child to the entire sequence.

A frequent use of this capability is a nested pattern (usually mentioning case classes):

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

Here, the target of the match is tested to see if it is an instance of Expr and if it is, op is bound to the Expr's operator, lhs and rhs are bound to its left- and right-hand sides, resp. and expr is bound to the Expr instance itself.


Elem is not a case class, it is an "ordinary" class with a companion object. There is a way to write ordinary (non-case) classes to simulate case classes. But more typically one views case classes as a shorthand for writing a bunch of boilerplate code, some of it in the class and some of it in an implicitly created companion. In this case, the pertinent bits are the unapply and / or unapplySeq methods in the companion object. These methods are what make non-case classes amenable to pattern matching.

For Elem the pertinent matching "signature" is that of object scala.xml.Elem#unapplySeq(...), specifically:

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

There you can see the pattern of bindings created when matching with Elem. They do in fact correspond to the pattern you're using in your sample code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜