在Scala中,如何使用transformer/Rewrite规则将递增ID放入XML元素中
我想读入一个XML文件,并在特定元素中放入一个递增的id。下面是我编写的一些测试代码,以了解如何做到这一点:在Scala中,如何使用transformer/Rewrite规则将递增ID放入XML元素中,xml,scala,scala-xml,Xml,Scala,Scala Xml,我想读入一个XML文件,并在特定元素中放入一个递增的id。下面是我编写的一些测试代码,以了解如何做到这一点: import scala.xml._ import scala.xml.transform._ val testXML = <document> <authors> <author> <first-name>Firstname</first-name> <last-n
import scala.xml._
import scala.xml.transform._
val testXML =
<document>
<authors>
<author>
<first-name>Firstname</first-name>
<last-name>Lastname</last-name>
</author>
</authors>
</document>
def addIDs(node : Node) : Node = {
object addIDs extends RewriteRule {
var authorID = -1
var emailID = -1
var instID = -1
override def transform(elem: Node): Seq[Node] =
{
elem match {
case Elem(prefix, "author", attribs, scope, _*) =>
//println("element author: " + elem.text)
if ((elem \ "@id").isEmpty) {
println("element id is empty:" + elem\"@id")
authorID += 1
println("authorID is " + authorID)
elem.asInstanceOf[Elem] % Attribute(None, "id", Text(authorID.toString), Null)
} else {
elem
}
case Elem(prefix, "email", attribs, scope, _*) =>
println("EMAIL")
elem.asInstanceOf[Elem] % Attribute(None, "id", Text(authorID.toString), Null)
case Elem(prefix, "institution", attribs, scope, _*) =>
println("INST")
elem.asInstanceOf[Elem] % Attribute(None, "id", Text(instID.toString), Null)
case other =>
other
}
}
}
object transform extends RuleTransformer(addIDs)
transform(node)
}
val newXML = addIDs(testXML)
导入scala.xml_
导入scala.xml.transform_
val testXML=
名字
姓氏
def addIDs(节点:节点):节点={
对象添加扩展了重写规则{
var authorID=-1
var emailID=-1
var institd=-1
覆盖def变换(元素:节点):Seq[节点]=
{
元素匹配{
案例元素(前缀“作者”,属性,范围,*)=>
//println(“元素作者:+elem.text”)
if((elem\“@id”).isEmpty){
println(“元素id为空:“+elem\”@id”)
authorID+=1
println(“authord是”+authord)
元素asInstanceOf[elem]%属性(无,“id”,文本(authorID.toString),Null)
}否则{
元素
}
案例元素(前缀“电子邮件”、属性、范围,*)=>
println(“电子邮件”)
元素asInstanceOf[elem]%属性(无,“id”,文本(authorID.toString),Null)
案例要素(前缀“机构”、属性、范围等)=>
println(“INST”)
元素asInstanceOf[elem]%属性(无,“id”,文本(Instit.toString),Null)
案例其他=>
其他
}
}
}
对象变换扩展规则转换器(addIDs)
变换(节点)
}
val newXML=addIDs(testXML)
此代码是功能性的-但是,ID没有按预期显示:
element id is empty:
authorID is 0
element id is empty:
authorID is 1
element id is empty:
authorID is 2
element id is empty:
authorID is 3
element id is empty:
authorID is 4
element id is empty:
authorID is 5
element id is empty:
authorID is 6
element id is empty:
authorID is 7
newXML:scala.xml.Node=<document>
<authors>
<author id="7">
<first-name>Firstname</first-name>
<last-name>Lastname</last-name>
</author>
</authors>
</document>
元素id为空:
authorID为0
元素id为空:
authorID是1
元素id为空:
作者是2
元素id为空:
作者是3
元素id为空:
作者是4
元素id为空:
作者是5岁
元素id为空:
作者是6岁
元素id为空:
作者7岁
newXML:scala.xml.Node=
名字
姓氏
看起来转换器多次命中每个节点,增加id,然后在id达到7时停止。为什么在最终完成之前它会多次接触节点?我是否可以做一些不同的事情来告诉它完成该节点
我认为它可能正在遍历新修改的节点,因此我检查了包含名为“id”的属性的元素。但这似乎不起作用。也许一开始这样做是个坏主意
谢谢你在这方面的帮助 看起来我遇到了这个scala bug:-BasicTransformer具有指数级的复杂性
我的解决方法是这样做的:当你编辑一个元素时,似乎转换的东西会更多地递归。我看了一会儿这个问题就解决不了了。相反,使用这种技术,效果很好,而且一开始似乎更有效。我发现了这个错误: