0
考慮這個例子如何在父節點在XML文檔中不唯一時將節點添加到XML?
import scala.xml.{Node, Elem}
import scala.xml.transform.{RewriteRule, RuleTransformer}
val doc: Elem =
<root>
<level1>
<Weekly>
<Properties>
<Property key="Sun"/>
<Property key="Mon"/>
<Property key="Tue"/>
</Properties>
</Weekly>
</level1>
<level2>
<Monthly>
<Properties>
<Property key="Jan"/>
<Property key="Feb"/>
<Property key="Mar"/>
</Properties>
</Monthly>
</level2>
</root>
val wednesday = <Property key="Wed"/>
final class AddNewDayRule extends RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case e: Elem if e.label == "Properties" => e.copy(child = e.child ++ wednesday)
case e => e
}
}
val addWed = new RuleTransformer(new AddNewDayRule).transform(doc).head
結果是
addWed: scala.xml.Node = <root>
<level1>
<Weekly>
<Properties>
<Property key="Sun"/>
<Property key="Mon"/>
<Property key="Tue"/>
<Property key="Wed"/></Properties>
</Weekly>
</level1>
<level2>
<Monthly>
<Properties>
<Property key="Jan"/>
<Property key="Feb"/>
<Property key="Mar"/>
<Property key="Wed"/></Properties>
</Monthly>
</level2>
</root>
正如你所看到的財產<Property key="Wed"/>
在Monthly
加入,以及因爲Properties
不是唯一的。
我也試圖限制我傳遞給transform
val addWed = new RuleTransformer(new AddNewDayRule).transform(doc \\ "Weekly").head
XML文檔的一部分,但我得到的是
addWed: scala.xml.Node = <Weekly>
<Properties>
<Property key="Sun"/>
<Property key="Mon"/>
<Property key="Tue"/>
<Property key="Wed"/></Properties>
</Weekly>
,而不是整個文件。
解決此問題的最佳方法是什麼?
更新
我試圖解決這個問題的一般路徑,我嘗試低於
final class AddNewNodeRule(expectedPath: Array[String], newNode: Node) extends RewriteRule {
private var index = 0
private val currentPath = Array[String]()
// only one transformation. If multiple, take expectedCount as input
var transformed = false
override def transform(ns: Seq[Node]): Seq[Node] = ns match {
case e: Node if index < expectedPath.length && e.label == expectedPath(index) =>
currentPath(index) = e.label
index += 1
println(s"i.inc = $index")
e
case e: Node if index == expectedPath.length - 1
&& (expectedPath sameElements currentPath) && !transformed =>
transformed = true
println(s"i.done = $index")
//e.copy(child = e.child ++ newNode)
e
case other: Node =>
println(s"i.other = $index, label=${other.label}")
other
}
}
val wednesday = <Property key="Wed"/>
val expectedPath = Array("level1", "Weekly", "Properties")
new RuleTransformer(new AddNewNodeRule(expectedPath, wednesday)).transform(doc).head
,但現在它作爲
wednesday: scala.xml.Elem = <Property key="Wed"/>
expectedPath: Array[String] = Array(level1, Weekly, Properties)
i.other = 0, label=#PCDATA
i.other = 0, label=#PCDATA
i.other = 0, label=#PCDATA
i.other = 0, label=#PCDATA
i.other = 0, label=Property
i.other = 0, label=#PCDATA
i.other = 0, label=Property
i.other = 0, label=#PCDATA
i.other = 0, label=Property
i.other = 0, label=#PCDATA
i.other = 0, label=Properties
i.other = 0, label=#PCDATA
i.other = 0, label=Weekly
i.other = 0, label=#PCDATA
java.lang.ArrayIndexOutOfBoundsException: 0
at #worksheet#.AddNewNodeRule.transform(scratch_13.scala:36)
at scala.xml.transform.RuleTransformer.$anonfun$transform$1(scratch_13.scala:11)
at scala.collection.IndexedSeqOptimized.foldLeft(scratch_13.scala:52)
at scala.collection.IndexedSeqOptimized.foldLeft$(scratch_13.scala:60)
at scala.collection.mutable.WrappedArray.foldLeft(scratch_13.scala:30)
at scala.xml.transform.RuleTransformer.transform(scratch_13.scala:11)
at scala.xml.transform.BasicTransformer.$anonfun$transform$2(scratch_13.scala:31)
at scala.collection.TraversableLike.$anonfun$flatMap$1(scratch_13.scala:237)
at scala.collection.mutable.ResizableArray.foreach(scratch_13.scala:55)
at scala.collection.mutable.ResizableArray.foreach$(scratch_13.scala:48)
at scala.collection.mutable.ArrayBuffer.foreach(scratch_13.scala:44)
at scala.collection.TraversableLike.flatMap(scratch_13.scala:237)
at scala.collection.TraversableLike.flatMap$(scratch_13.scala:234)
at scala.collection.AbstractTraversable.flatMap(scratch_13.scala:100)
at scala.xml.transform.BasicTransformer.transform(scratch_13.scala:31)
at scala.xml.transform.BasicTransformer.transform(scratch_13.scala:41)
at scala.xml.transform.RuleTransformer.transform(scratch_13.scala:11)
at #worksheet#.#worksheet#(scratch_13.scala:54)
我不知道該怎麼做下一個失敗
謝謝@Amir。我試圖解決這個一般路徑(以便它可以重用)。我將上面的嘗試添加爲更新,但失敗。讓我知道你是否知道這件事。謝謝 – daydreamer