如何从非前缀的命名空间标记中读取Scala Scales XML中的属性

时间:2014-02-04 17:56:52

标签: xml scala

我正在使用Scales XML和Scala。

我正在尝试阅读MediaWiki XML格式,它是这样开始的:

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.8/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.8/ http://www.mediawiki.org/xml/export-0.8.xsd" version="0.8" xml:lang="en">

然后在标签下面有一堆标签,其中一些标签有一个重定向标签,如:

<page>
   <title>Albigensian</title>
   <redirect title="Catharism" />
   <revision>
      ...
   </revision>
</page>

我正在使用ScalesXML进行解析:

object WikiMediaImport extends App with Logging {
   val xml = pullXml(new FileReader(args(0)))

   val ns = Namespace("http://www.mediawiki.org/xml/export-0.8/")
   val p = ns // .prefixed("mediawiki") <-- that doesn't help either
   val mediawikiTag = p("mediawiki")
   val pageTag = p("page")
   val titleTag = p("title")
   val revisionTag = p("revision")
   val textTag = p("text")
   val timestampTag = p("timestamp")
   val redirectTag = p("redirect")
 //val redirectWhereAttr: Attribute = Attribute(redirectTag, "title")

   val pagePath = List(mediawikiTag, pageTag)
   val iterator =  iterate(pagePath, xml)

   for {
     page <- iterator
   } {
     val title = text(page \* titleTag)
     val timestamp = text(page \* revisionTag \* timestampTag)
     val content = text(page \* revisionTag \* textTag)

     println(s"$title $timestamp ${content.length}")
   }
}

但是,我还希望得到mediawiki -> page -> redirect[title]属性值,尽管阅读help page,我仍然不确定如何执行此操作。

如果我得到一个带前缀的命名空间,则找不到任何内容,因为在该文件中,命名空间实际上没有前缀。如果我使用NoNamespaceQName则找不到任何内容(可能是因为实际上XML文件指定了命名空间)。

如果我使用默认的命名空间,那么Scales不允许我定义属性,因为它们只能用于带前缀的命名空间。

至少我就是这么理解的。

2 个答案:

答案 0 :(得分:2)

访问属性需要AttributeQName(NoNamespaceQName或PrefixedQName)。 * @的简单字符串版本仅在localName上进行比较,这是我将弃用的错误,UnprefixedQName重载版本也是如此。它们有助于使查询更容易构建,但它们对规范类型不正确,并且可能会在以后咬人(包括我)。

\ @ name是NoNamespaceQName(与上面的重定向标题属性一样)。 \ @p:name是一个PrefixedQName,唯一的另一种指定方式是通过谓词,这也应该是谓词。

编辑添加实际的“将来不要弃用”答案,抱歉:) - 由于此属性未命名空间,您应该在字符串Function Docs here上使用“l”函数或直接创建NoNamespaceQName通过NoNamespaceQName(localString)并使用它。 See more here on the implicits and QNames in general

答案 1 :(得分:0)

找到答案,需要使用*@运算符和一个简单的String来访问属性:

val redirectWhereAttr = "title".l

...

val redirectWhere = text(page \* redirectTag *@ redirectWhereAttr)