我正在使用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不允许我定义属性,因为它们只能用于带前缀的命名空间。
至少我就是这么理解的。
答案 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)