Правило перезаписи XML Scala (или простая справка по шаблону) - PullRequest
0 голосов
/ 29 мая 2010

Мне не хватает довольно простого синтаксиса, который я собираю. Я пытаюсь переписать метку элемента на что-то другое и сохранить все остальное без изменений.

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) Что именно означает "ребенок @ _ *" на простом английском языке?

2) Как я могу зафиксировать значение "child @ _ *" и просто передать его новому элементу? В настоящее время я получаю следующую ошибку, которая имеет смысл.

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

Я тоже не привержен этому, поэтому, если есть лучший способ просто изменить имя элемента определенного узла, давайте здесь это ...

Спасибо, --tim

Ответы [ 2 ]

5 голосов
/ 29 мая 2010

Обозначения:

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

Позволяет сопоставить значение «в пределах» (часть patternConstraint) при захвате общего значения, на которое распространяется это ограничение (как bindVar).

В вашем конкретном случае, child @ _*, _ означает «все равно», * означает последовательность значений, а child @ означает привязать дочерний элемент ко всей последовательности.

Частое использование этой возможности - это вложенный шаблон (обычно с упоминанием классов дел):

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

Здесь цель совпадения проверяется, чтобы определить, является ли она экземпляром Expr, и если это так, op связан с оператором Expr, lhs и rhs связаны с левой и правой сторонами, соотв. и expr привязан к самому экземпляру Expr.

1 голос
/ 29 мая 2010

Elem это не класс case, это «обычный» класс с сопутствующим объектом. Существует способ написать обычные (не-case) классы для имитации case-классов. Но, как правило, классы case рассматриваются как сокращение для написания набора шаблонного кода, некоторые из которых в классе, а некоторые в неявно созданном компаньоне. В этом случае подходящими битами являются методы unapply и / или unapplySeq в сопутствующем объекте. Эти методы делают классы без регистра пригодными для сопоставления с образцом.

Для Elem соответствующая совпадающая "подпись" соответствует object scala.xml.Elem#unapplySeq(...), а именно:

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

Там вы можете увидеть шаблон привязок, созданных при сопоставлении с Elem. На самом деле они соответствуют шаблону, который вы используете в своем примере кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...