Scala: 解析XML属性

12

我正在尝试解析一个类似这样的 RSS 源以获取 "date" 属性:

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

但是似乎什么都不起作用。我错过了什么吗?

真的非常感谢任何帮助!


1
rssFeed?不应该是rss吗? - VonC
1
rssFeed是一个包含RSS数据的变量。 - Chris
4个回答

20

<y:c 中的 "y" 是命名空间前缀,不是名称的一部分。此外,属性用 '@' 表示。试试这样:

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

14

使用"@attrName"选择器来检索属性。 因此,您的选择器实际上应该类似于以下内容:

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

1
请注意使用 .text 将日期作为字符串而不是节点返回。 - sblundy
1
确实。text方法通常比toString更可取,因为它可以优雅地处理选择器抓取了XML块而不是Text节点的情况。 - Daniel Spiewak

3

考虑使用序列推导式。它们对于处理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
此外,请考虑\\\之间的区别。\\会查找后代,而不仅仅是子级,就像这样(请注意,它从通道跳到c,没有在item中停留):
scala> (rssFeed \\ "channel" \\ "c" \ "@date").text
res20: String = AA

如果您只想获取所有 < c > 元素,而不关心它们的父元素,则可以使用类似以下方式的代码:
scala> (rssFeed \\ "c" \ "@date").text            
res24: String = AA

这指定了一个精确的路径:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接