Scala: синтаксический анализ XML-атрибутов - PullRequest
12 голосов
/ 17 мая 2010

Я пытаюсь проанализировать RSS-канал, который выглядит следующим образом для атрибута "дата":

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

Я пробовал несколько разных версий этого: (rssFeed содержит данные RSS)

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

Но, похоже, ничего не работает. Чего мне не хватает?

Любая помощь будет принята с благодарностью!

Ответы [ 4 ]

19 голосов
/ 17 мая 2010

"y" в <y:c является префиксом пространства имен. Это не часть имени. Кроме того, атрибуты обозначаются знаком «@». Попробуйте это:

println(((rssFeed \\ "channel" \\ "item" \ "c" \ "@date").toString))
14 голосов
/ 17 мая 2010

Атрибуты извлекаются с помощью селектора «@attrName». Таким образом, ваш селектор должен выглядеть примерно так:

println((rssFeed \\ "channel" \\ "item" \ "c" \ "@date").text)
3 голосов
/ 12 ноября 2011

Подумайте и об использовании последовательности пониманий. Они полезны для работы с XML, особенно если вам нужны сложные условия.

Для простого случая:

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

Дает вам атрибут даты из всего, что есть в 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)
}

Дает вам:

    <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
3 голосов
/ 18 мая 2010

Также подумайте о разнице между \ и \\ . \\ ищет потомка, а не просто ребенка, вот так (обратите внимание, что он переходит с канала на c без элемента):

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

Или такого рода вещи, если вы просто хотите все элементы и не заботитесь о своих родителях:

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

И это указывает точный путь:

scala> (rssFeed \ "channel" \ "item" \ "c" \ "@date").text
res25: String = AA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...