2010-05-17 19 views
11

Próbuję analizować kanał RSS, który wygląda tak dla atrybutu „data”:Scala: XML Atrybut parsowania

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

Próbowałem kilka różnych wersji tego: (rssFeed zawiera dane RSS)

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

Ale nic nie działa. czego mi brakuje?

Każda pomoc będzie naprawdę doceniona!

+1

'rssFeed'? Czy nie powinno to być "rss"? – VonC

+1

rssFeed jest zmienną zawierającą dane RSS – Chris

Odpowiedz

18

"y" w <y:c jest prefiksem przestrzeni nazw. To nie jest część nazwy. Ponadto atrybuty są określane za pomocą znaku "@". Wypróbuj to:

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

Atrybuty są pobierane za pomocą selektora "@attrName". Zatem Twój selektor powinny być rzeczywiście coś jak poniżej:

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

Zwróć uwagę na .text, aby uzyskać datę raczej jako ciąg niż węzeł – sblundy

+1

. Metoda "tekstowa" jest na ogół lepsza od 'toString', ponieważ będzie z wdziękiem obsługiwać przypadek, w którym twój selektor porwał fragment XML zamiast węzła' Text'. –

3

także pomyśleć o różnicy między \ i \\. \\ wygląda na potomka, a nie tylko dziecko, tak (zauważ, że przeskakuje z kanału do C, bez elementu):

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

albo to coś takiego, jeśli chcesz po prostu cały < c > elementy, a nie dba o swoich rodziców:

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

i to określa dokładną ścieżkę:

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

myśleć o użyciu listowych kolejności, zbyt. Są przydatne do obsługi XML-a, szczególnie jeśli potrzebujesz skomplikowanych warunków.

Dla prostego przypadku:

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

Daje atrybut data od wszystkiego w rssFeed.

Ale jeśli chcesz coś bardziej złożona:

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

Daje:

<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 
Powiązane problemy