こんな感じか?
def changeTagName[T >: Node](from: String, to: String)(in: T): T = in match {
case Elem(p, l, a, ns, child @ _*) =>
val label = if (l == from) to else l
Elem(p, label, a, ns, child.map(changeTagName(from, to)(_)): _*)
case x => x
}
使用例
scala> val hoge2moge = changeTagName("hoge", "moge") _
scala> hoge2moge: (scala.xml.Node) => scala.xml.Node = <function>
scala> hoge2moge(<pre:hoge attr="value">parentText<child:hoge>childtext</child:hoge></pre:hoge>)
scala> res17: scala.xml.Node = <pre:moge attr="value">parentText<child:moge>childtext</child:moge></pre:moge>
追記:さらに汎用化してみた
高階関数化して、引数に名前を変更するための関数を渡せるようにした。
def changeTagName[T >: Node](changeFunc: (String) => String)(in: T): T = in match {
case Elem(p, l, a, ns, child @ _*) =>
Elem(p, changeFunc(l), a, ns, child.map(changeTagName(changeFunc)(_)): _*)
case x => x
}
使用例
お題はこちら。
scala> val c = changeTagName(s => if (List("moge", "koge").contains(s)) "bege" else s) _
c: (scala.xml.Node) => scala.xml.Node = <function>
scala> c(x)
res6: scala.xml.Node =
<lage>
<hoge>
<bege></bege>
<bege></bege>
</hoge>
<hoge>
<bege></bege>
<bege></bege>
</hoge>
</lage>
23:52 さらにちょっと修正
flatMap使えば別にNodeSeq渡せることに気がついた。
def changeTagName(changeFunc: (String) => String)(in: NodeSeq): NodeSeq = in match {
case Elem(p, l, a, ns, child @ _*) =>
Elem(p, changeFunc(l), a, ns, child.flatMap(changeTagName(changeFunc)(_)): _*)
case x => x
}
0 件のコメント:
コメントを投稿