scala xml重写规则(或简单模式帮助)

时间:2010-05-29 14:21:22

标签: xml scala

我错过了一些我收集的相当简单的语法。我正在尝试将元素标签重写为其他内容,并保持其他所有内容不变。

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
 }
}

现在,我要求解释两件事:

1)“child @ _ *”究竟用简单的英语表示什么?

2)如何捕获“child @ _ *”的值并让它直接传递给新元素?目前,我得到以下错误,这是有道理的。

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

我也不喜欢这个,所以如果有一个更好的方法来简单地更改特定节点的元素名称,那就让它吧......

谢谢, --tim

2 个答案:

答案 0 :(得分:5)

符号:

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

允许您在捕获受约束的整体值(作为bindVar)时匹配值(patternConstraint部分)内的“内部”。

在您的特定情况下,child @ _*_表示“不关心”,*表示一系列值,child @表示将子项绑定到整个序列。

频繁使用此功能是嵌套模式(通常提到案例类):

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

在这里,测试匹配的目标以查看它是否是Expr的实例,如果是,op绑定到Expr的运算符,{{ 1}}和lhs分别绑定在左侧和右侧。并且rhs绑定到Expr实例本身。

答案 1 :(得分:1)

Elem不是案例类,它是带有伴随对象的“普通”类。有一种方法可以编写普通(非案例)类来模拟案例类。但更典型的是,一个视图案例类作为编写一堆样板代码的简写,其中一些在类中,一些在隐式创建的伴随中。在这种情况下,相关位是伴随对象中的unapply和/或unapplySeq方法。这些方法使非案例类适合模式匹配。

对于Elem,相关的匹配“签名”是object scala.xml.Elem#unapplySeq(...)的签名,具体为:

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

在那里,您可以看到与Elem匹配时创建的绑定模式。它们确实对应于您在示例代码中使用的模式。