代码之家  ›  专栏  ›  技术社区  ›  Chris

scala:xml属性解析

  •  11
  • Chris  · 技术社区  · 14 年前

    我正在尝试为属性“日期”解析类似于此的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 回复  |  直到 13 年前
        1
  •  18
  •   sblundy    14 年前

    中的“Y” <y:c 是命名空间前缀。它不是名字的一部分。此外,属性也用“@”表示。试试这个:

    println(((rssFeed \\ "channel" \\ "item" \ "c" \ "@date").toString))
    
        2
  •  14
  •   Daniel Spiewak    14 年前

    使用“@attrname”选择器检索属性。因此,您的选择器实际上应该如下所示:

    println((rssFeed \\ "channel" \\ "item" \ "c" \ "@date").text)
    
        3
  •  3
  •   James Moore    14 年前

    另外,考虑一下 \ \\ . \\ 查找子代,而不仅仅是子代,如下所示(请注意,它从通道跳到C,不带项):

    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
    
        4
  •  3
  •   James Moore    13 年前

    也可以考虑使用序列理解。它们对于处理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