3

我想读入一个 XML 文件并在特定元素中放置一个递增的 id。这是我编写的一些测试代码,用于弄清楚如何做到这一点:

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)

此代码是功能性的 - 但是,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,然后当 id 达到 7 时最终停止。为什么它在最终完成之前接触节点这么多次?有什么我可以做不同的事情来告诉它完成那个节点吗?

我想也许它正在遍历新修改的节点,因此我检查了包含名为“id”的属性的元素。但这似乎不起作用。也许一开始就这样做是个坏主意?

感谢您对此的任何帮助。

4

1 回答 1

0

看起来我遇到了这个 scala 错误: https ://issues.scala-lang.org/browse/SI-3689 - BasicTransformer 具有指数复杂性

我的解决方法是这样做:https ://stackoverflow.com/a/1089519/3935595

于 2014-08-15T12:28:37.317 回答