Voici deux (rendent maintenant trois) les solutions possibles. Le premier est assez rapide et sale. Vous pouvez exécuter tout le bit dans l'interpréteur 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
sera "val2", et dog
sera "val1".
Notez que si l'un des noeuds est introuvable, une chaîne vide sera retournée. Vous pouvez travailler autour de cela, ou vous pouvez l'écrire d'une manière un peu plus idiomatiques:
// 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
sera « val2 », dog1
sera « val1 », et goat
sera « pas de chèvre trouvé. »
MISE À JOUR: Voici une méthode plus pratique pour prendre une liste de noms de balises et retourner leurs matchs en tant que carte [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)
Si vous exécutez que, matchedValues
sera Map(dog -> val1, cat -> val2)
.
Espérons que ça aide! Par la suggestion de Daniel, j'utilise l'opérateur double-backslash, qui descendra dans les éléments enfants, ce qui peut être meilleur au fur et à mesure de l'évolution de votre jeu de données XML.
Merci! Pouvez-vous montrer un exemple en utilisant une expression de rendement? Ou au moins une bonne URL qui parle d'eux. Comme je l'ai dit, je suis un newb =) –
Ce n'était pas tout à fait ce que je voulais dire. En définissant une fonction qui renvoie une valeur - ici, un Tuple2 [String, String] - vous avez maintenant une expression disponible, car l'appel d'une fonction qui renvoie une valeur est une expression. Déclarer et initialiser un "val" est lui-même une déclaration, et le membre de droite (la valeur initiale) doit être une expression, pas une déclaration. Cela signifie que le membre de droite peut être une valeur littérale ou une invocation de fonction, mais il ne peut s'agir d'une ou de plusieurs instructions. C'est cette distinction entre les énoncés et les expressions qui encourage souvent à écrire ces petites fonctions. – seh