2011-09-27 234 views
5

任何可以簡化以下內容的方法?或用另一個函數來減少樣板代碼?Scala XML,獲取父節點屬性值匹配的節點

scala> val ns = <foo><bar id="1"><tag>one</tag><tag>uno</tag></bar><bar id="2"><tag>two</tag><tag>dos</tag></bar></foo> 
ns: scala.xml.Elem = <foo><bar id="1"><tag>one</tag><tag>uno</tag></bar><bar id="2"><tag>two</tag><tag>dos</tag></bar></foo> 

scala> (ns \\ "bar" filterNot{_ \\ "@id" find { _.text == "1" } isEmpty}) \\ "tag" 
res0: scala.xml.NodeSeq = NodeSeq(<tag>one</tag>, <tag>uno</tag>) 

回答

15

我只能找到一個小的改進,find/isEmpty測試可以用exists更換:

澄清意見後
(ns \\ "bar" filter { _ \\ "@id" exists (_.text == "1") }) \\ "tag" 

編輯:

這是一個非常不錯的主意!試試這個大小:

import xml._ 

implicit def richNodeSeq(ns: NodeSeq) = new { 

    def \@(attribMatch: (String, String => Boolean)): NodeSeq = 
    ns filter { _ \\ ("@" + attribMatch._1) exists (s => attribMatch._2(s.text)) } 

} 

ns \\ "bar" \@ ("id", _ == "1") \\ "tag" 

我用一個謂詞,而不是硬編碼的屬性值比較。

+1

感謝您的改進。我真正想要的是一種創建過濾器選擇器的方法{_ \\「@id」exists(_.text ==「1」)})然後它看起來像(x \\「bar」\ @(「@id」,「1」)\\「tag」 – eptx

+0

我喜歡你的想法,我已經用可能的解決方案編輯了我的答案。 – Lachlan