2012-10-15 20 views
5

您是否知道任何Scala API根據XPath插入和(或)更新節點?例如,對於一個給定的節點和XPath,這個API將創建XML的副本,新的節點scala - XML插入/更新

感謝

+0

Xpath是一種查詢語言。據我記得你不能更新或寫它。你的意思是xslt嗎? – Jan

+0

XPath將用於「選擇」一個節點,並提供一個將作爲子節點添加到此「父」節點的節點。順便說一句。我知道,Scala XML是不可變的,但是有沒有什麼可能的方法,如何完成這個任務? – user1746915

+0

[this]怎麼樣?(http://stackoverflow.com/questions/4018300/substitution-xml-values-programatically-with-scala)問題?它展示瞭如何使用scala xml更新節點... – Jan

回答

0

我會做的是分析使用\\

XML中的XML轉換爲使用.toList.last.text列表

追加我需要的東西,然後收集我的選項:jsonOption collect在這裏,您可以使用orElse Some再次更改一些選項,然後使用for yield來產生我想要的xml。

利用規模在數據轉換中的靈活性。它不一定是相同的,但我相信你可以看到燈光...

6

您可以使用RewriteRule來做到這一點,2.10.3 documentation

val cats = <Cats> 
    <Cat Name="Floyd"/> 
    <Cat Name="Onyx"/> 
</Cats> 

然後假定RewriteRule

class AddCat(name: String) extends RewriteRule { 
    override def transform(n: Node): Seq[Node] = n match { 
    case e: Elem if e.label == "Cats" => 
     val cats = (e \\ "Cat") 
     val newCat = <Cat Name={name}/> 
     new Elem(e.prefix, "Cats", e.attributes, e.scope, e.minimizeEmpty, (cats ++ newCat).toSeq:_*) 
    case x => x 
    } 
} 

那麼你可以做,

val rule = new RuleTransformer(new AddCat("Stevie")) 
rule.transform(cats) 
res2: Seq[scala.xml.Node] = List(<Cats><Cat Name="Floyd"/><Cat Name="Onyx"/><Cat Name="Stevie"/></Cats>) 

同樣,如果你想改變這些Appro公司的屬性

class AddLastName(name: String, lastName: String) extends RewriteRule { 
    override def transform(n: Node): Seq[Node] = n match { 
    case e: Elem if e.label == "Cat" && (e \\ "@Name" text).equals(name) => 
     val cat: String = e.attributes("Name").head.text 
     e % Attribute(None, "Name", Text(s"$name $lastName"), Null) 
    case x => x 
    } 
} 

val rule = new RuleTransformer(new AddLastName("Stevie", "Nicks")) 
rule.transform(cats) 
res3: Seq[scala.xml.Node] = List(<Cats><Cat Name="Floyd"/><Cat Name="Onyx"/><Cat Name="Stevie Nicks"/></Cats>) 

兩個疼痛會做你想要的。困難的部分是弄清楚如何找到孩子,然後構建父節點。

+0

也是這樣的:http://stackoverflow.com/a/4019294/1274818 – tysonjh

+0

這是SO上最好的答案之一。我無法相信它沒有得到更多的讚揚,也沒有被標記爲正確的。我看了很多其他人,但這是最有幫助的。非常感謝@tysonjh。 – Philippe