这里有两个(现在变成三个)可能的解决方案。第一个非常快速和肮脏。您可以在 Scala 解释器中运行全部内容。
val xmlData = <outertag>
<dog>val1</dog>
<cat>val2</cat>
</outertag>
// A very simple way to do this mapping.
def simpleGetNodeValue(x:scala.xml.NodeSeq, tag:String) = (x \\ tag).text
val cat = simpleGetNodeValue(xmlData, "cat")
val dog = simpleGetNodeValue(xmlData, "dog")
cat
将是“val2”,dog
将是“val1”。
请注意,如果没有找到任何一个节点,将返回一个空字符串。你可以解决这个问题,或者你可以用一种更惯用的方式来编写它:
// A more idiomatic Scala way, even though Scala wouldn't give us nulls.
// This returns an Option[String].
def getNodeValue(x:scala.xml.NodeSeq, tag:String) = {
(x \\ tag).text match {
case "" => None
case x:String => Some(x)
}
}
val cat1 = getNodeValue(xmlData, "cat") getOrElse "No cat found."
val dog1 = getNodeValue(xmlData, "dog") getOrElse "No dog found."
val goat = getNodeValue(xmlData, "goat") getOrElse "No goat found."
cat1
将是“val2”,dog1
将是“val1”,并且goat
将是“No goat found”。
更新:这是获取标签名称列表并将其匹配项作为 Map[String, String] 返回的另一种便捷方法。
// Searches for all tags in the List and returns a Map[String, String].
def getNodeValues(x:scala.xml.NodeSeq, tags:List[String]) = {
tags.foldLeft(Map[String, String]()) { (a, b) => a(b) = simpleGetNodeValue(x, b)}
}
val tagsToMatch = List("dog", "cat")
val matchedValues = getNodeValues(xmlData, tagsToMatch)
如果你运行它,matchedValues
将是Map(dog -> val1, cat -> val2)
.
希望有帮助!
更新 2:根据 Daniel 的建议,我正在使用双反斜杠运算符,它将下降到子元素中,随着 XML 数据集的发展,这可能会更好。