2010-05-17 11 views
11

Sto cercando di analizzare un feed RSS che assomiglia a questo per l'attributo "Data":Scala: attributo XML parsing

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

Ho provato diverse versioni di questo: (RSS feed contiene i dati RSS)

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

Ma niente sembra funzionare. Cosa mi manca?

Qualsiasi aiuto sarebbe davvero apprezzato!

+1

'rssFeed':

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

Ti dà? Non dovrebbe essere 'rss'? – VonC

+1

rssFeed è una variabile che contiene i dati RSS – Chris

risposta

18

La "y" in <y:c è un prefisso dello spazio dei nomi. Non fa parte del nome. Inoltre, gli attributi sono indicati con un '@'. Prova questo:

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

Gli attributi vengono recuperati utilizzando il selettore "@attrName". Così, il vostro selettore dovrebbe essere effettivamente qualcosa di simile al seguente:

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

Nota il .text per ottenere la data come stringa anziché come nodo – sblundy

+1

Infatti. Il metodo 'text' è generalmente preferibile a' toString' dato che gestirà con grazia il caso in cui il tuo selettore ha afferrato un blocco XML piuttosto che un nodo 'Text'. –

3

Inoltre, pensare alla differenza tra \ e \\. \\ cerca un discendente, non solo un bambino, come questo (si noti che salta da canale a C, senza articolo):

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

O questo genere di cose se si desidera solo tutto il < c > elementi, e non si preoccupano dei loro genitori:

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

e questa specifica un percorso esatto:

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

pensare di utilizzare comprehensions sequenza, anche. Sono utili per trattare con XML, in particolare se hai bisogno di condizioni complicate.

Per il caso semplice:

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

vi dà l'attributo di data da tutto in RSS feed.

Ma se volete qualcosa di più complesso:

<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