好的,我试了一下。正如其他人所建议的那样,我也在使用一个属性。对于将在列表内容之后生成元素 named 的版本,而不是使用属性,还有几行注释。
这项工作的困难部分由下面的类完成,它接受一个字符串列表并转换给定给它的节点,以便它们包含列表表示的节点层次结构。
import xml._
import transform._
class AddPath(l: List[String]) extends RewriteRule {
def listToNodes(l: List[String]): Seq[Node] = l match {
case Nil => Seq.empty
case first :: rest =>
<node>{listToNodes(rest)}</node> % Attribute("name", Text(first), Null)
//case first :: rest =>
//<node>{listToNodes(rest)}</node> copy (label = first)
}
def transformChild(child: Seq[Node]) = l match {
case Nil => child
case first :: rest =>
child flatMap {
case elem: Elem if elem.attribute("name") exists (_ contains Text(first)) =>
//case elem: Elem if elem.label == first =>
new AddPath(rest) transform elem
case other => Seq(other)
}
}
def appendToOrTransformChild(child: Seq[Node]) = {
val newChild = transformChild(child)
if (newChild == child)
child ++ listToNodes(l)
else
newChild
}
override
def transform(n: Node): Seq[Node] = n match {
case elem: Elem => elem.copy(child = appendToOrTransformChild(elem.child))
case other => other
}
}
在这之后事情变得非常简单。首先,我们创建列表,然后从中生成规则列表。
val listOfStrings = List(List("Node0", "Node00", "Leaf0"),
List("Node0", "Node00", "Leaf1"),
List("Node1", "Leaf2"),
List("Node0", "Leaf3"),
List("Node2", "Node20", "Node200", "Leaf4"))
val listOfAddPaths = listOfStrings map (new AddPath(_))
接下来,我们根据这些规则创建一个规则转换器。
val ruleTransformer = new RuleTransformer(listOfAddPaths: _*)
最后,我们创建 XML 并漂亮地打印它。请注意,我正在添加一个根节点。如果您不想要它,只需获取它的child。另请注意,ruleTransformer 将返回一个带有单个节点的Seq[Node]——我们的结果。
val results = ruleTransformer(<root/>)
val prettyPrinter = new PrettyPrinter(80, 4)
results foreach { xml =>
println(prettyPrinter format xml)
}
还有输出:
<root>
<node name="Node0">
<node name="Node00">
<node name="Leaf0"></node>
<node name="Leaf1"></node>
</node>
<node name="Leaf3"></node>
</node>
<node name="Node1">
<node name="Leaf2"></node>
</node>
<node name="Node2">
<node name="Node20">
<node name="Node200">
<node name="Leaf4"></node>
</node>
</node>
</node>
</root>
替代版本的输出:
<root>
<Node0>
<Node00>
<Leaf0></Leaf0>
<Leaf1></Leaf1>
</Node00>
<Leaf3></Leaf3>
</Node0>
<Node1>
<Leaf2></Leaf2>
</Node1>
<Node2>
<Node20>
<Node200>
<Leaf4></Leaf4>
</Node200>
</Node20>
</Node2>
</root>