2010-05-17 36 views
11

Tôi đang cố gắng để phân tích một feed rss trông như thế này cho thuộc tính "ngày":Scala: XML Thuộc tính phân tích

<rss version="2.0"> 
<channel> 
    <item> 
     <y:c date="AA"></y:c> 
    </item> 
</channel> 
</rss> 

tôi đã cố gắng phiên bản khác nhau về điều này: (RSSFeed chứa dữ liệu RSS)

println(((rssFeed \\ "channel" \\ "item" \ "y:c" \"date").toString)) 

Nhưng dường như không có gì hiệu quả. Tôi đang thiếu gì?

Bất kỳ trợ giúp nào thực sự sẽ được đánh giá cao!

+1

'rssFeed'? Nó không phải là 'rss'? – VonC

+1

rssFeed là một biến containging các dữ liệu RSS – Chris

Trả lời

18

"y" trong <y:c là tiền tố không gian tên. Nó không phải là một phần của tên. Ngoài ra, các thuộc tính được gọi bằng '@'. Hãy thử điều này:

println(((rssFeed \\ "channel" \\ "item" \ "c" \ "@date").toString)) 
14

Thuộc tính được truy xuất bằng bộ chọn "@attrName". Vì vậy, chọn bạn thực sự nên giống như sau:

println((rssFeed \\ "channel" \\ "item" \ "c" \ "@date").text) 
+1

Lưu ý .tiếp theo để có được ngày như một String chứ không phải là một Node – sblundy

+1

Thật vậy. Phương thức 'text' thường thích hợp hơn với' toString' vì nó sẽ xử lý một cách duyên dáng trường hợp bộ chọn của bạn nắm lấy một đoạn XML thay vì một nút 'Văn bản'. –

3

Ngoài ra, suy nghĩ về sự khác biệt giữa \\\. \\ tìm kiếm một hậu duệ, không chỉ là một đứa trẻ, như thế này (lưu ý rằng nó nhảy từ kênh để c, mà không mục):

scala> (rssFeed \\ "channel" \\ "c" \ "@date").text 
res20: String = AA 

Hoặc các loại điều này nếu bạn chỉ muốn tất cả các < c > yếu tố, và không quan tâm đến các bậc phụ huynh:

scala> (rssFeed \\ "c" \ "@date").text    
res24: String = AA 

và điều này xác định một con đường chính xác:

scala> (rssFeed \ "channel" \ "item" \ "c" \ "@date").text 
res25: String = AA 
3

suy nghĩ về việc sử dụng comprehensions chuỗi, quá. Chúng hữu ích cho việc xử lý XML, đặc biệt nếu bạn cần các điều kiện phức tạp.

Đối với trường hợp đơn giản:

for { 
    c <- rssFeed \\ "@date" 
} yield c 

Cung cấp cho bạn các thuộc tính ngày từ tất cả mọi thứ trong RSSFeed.

Nhưng nếu bạn muốn một cái gì đó phức tạp hơn:

val rssFeed = <rss version="2.0"> 
       <channel> 
        <item> 
        <y:c date="AA"></y:c> 
        <y:c date="AB"></y:c> 
        <y:c date="AC"></y:c> 
        </item> 
       </channel> 
       </rss> 

val sep = "\n----\n" 

for { 
    channel <- rssFeed \ "channel" 
    item <- channel \ "item" 
    y <- item \ "c" 
    date <- y \ "@date" if (date text).equals("AA") 
} yield { 
    val s = List(channel, item, y, date).mkString(sep) 
    println(s) 
} 

Cung cấp cho bạn:

<channel> 
         <item> 
          <y:c date="AA"></y:c> 
          <y:c date="AB"></y:c> 
          <y:c date="AC"></y:c> 
         </item> 
         </channel> 
    ---- 
    <item> 
          <y:c date="AA"></y:c> 
          <y:c date="AB"></y:c> 
          <y:c date="AC"></y:c> 
         </item> 
    ---- 
    <y:c date="AA"></y:c> 
    ---- 
    AA 
Các vấn đề liên quan