2011-09-27 29 views
5

Bất kỳ cách nào để đơn giản hóa những điều sau đây? hoặc giảm mã boilerplate với một chức năng khác?Scala XML, Nhận các nút mà cha mẹ có giá trị thuộc tính khớp với

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>) 

Trả lời

15

tôi chỉ có thể tìm thấy một sự cải thiện đáng kể, các thử nghiệm find/isEmpty có thể được thay thế bằng exists:

(ns \\ "bar" filter { _ \\ "@id" exists (_.text == "1") }) \\ "tag" 

Chỉnh sửa sau khi làm rõ bình luận:

Đó là một ý tưởng thực sự tốt đẹp! Hãy thử kích thước này:

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" 

Tôi đã sử dụng vị từ thay vì mã hóa cứng so sánh giá trị thuộc tính.

+1

Cảm ơn bạn đã cải thiện. Những gì tôi thực sự tìm kiếm là một cách để tạo ra một bộ chọn cho bộ lọc {_ \\ "@id" tồn tại (_.text == "1")}) sau đó nó trông giống như (x \\ "bar" \ @ ("@id", "1") \\ "tag" – eptx

+0

Tôi thích ý tưởng của bạn. Tôi đã chỉnh sửa câu trả lời của mình bằng một giải pháp khả thi. – Lachlan

Các vấn đề liên quan