0
import scala.io.Source
import scala.xml.{Node, NodeSeq, XML}

object scalaTest extends App {


var test= <name>person
<fname>doe
<first>john</first>
</fname>
</name>


var s=scala.io.StdIn.readLine
var result=s.asInstanceOf[NodeSeq]

println(result)


}

When i provide xpath test\"fname"\"first" on command line, it throws,

test\"fname"\"first"
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to scala.xml.NodeSeq
    at scalaTest$.delayedEndpoint$scalaTest$1(scalaTest.scala:15)
    at scalaTest$delayedInit$body.apply(scalaTest.scala:4)
    at scala.Function0.apply$mcV$sp(Function0.scala:34)
    at scala.Function0.apply$mcV$sp$(Function0.scala:34)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App.$anonfun$main$1$adapted(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:389)
    at scala.App.main(App.scala:76)
    at scala.App.main$(App.scala:74)
    at scalaTest$.main(scalaTest.scala:4)
    at scalaTest.main(scalaTest.scala)

How to provide xpath as test\"fname"\"first" in command line and get result as,

<first>john</first>
1
  • I have no experience with XML in Scala, but shouldn't s be somehow relatated to test in your code? Or how are these related? Commented Mar 9, 2018 at 12:33

1 Answer 1

1

You cannot just cast a String into a NodeSeq. You could attempt to parse it with XML.loadString(...). But this is also not what you want, because your string does not contain xml, it contains some xpath-like selection. I don't know whether Scala's built-in XML actually supports Xpath. I only know that it has a few funny methods on NodeSeqs like \ and \\ that look somewhat like Xpath. What you could do is:

  • get input string from stdin
  • split your input string at the '\'-character
  • foldLeft the test-xml node using the \-method

Something like this works:

import scala.xml.NodeSeq
val test = <name>person<fname>doe<first>john</first></fname></name>
val xpath = """fname\first""" // or read from StdIn
val selectedElement = xpath.split("\\\\").foldLeft[NodeSeq](test){
  case (elem, tagName) => elem \ tagName 
}

// gives result:
// res20: scala.xml.NodeSeq = NodeSeq(<first>john</first>)

Or shorter:

val selectedElement = xpath.split("\\\\").foldLeft[NodeSeq](test)(_ \ _)

Another note: you of course cannot use the String "test" in your StdIn input. How is the compiler supposed to know that it has anything to do with the local test-variable?

Sign up to request clarification or add additional context in comments.

3 Comments

This works fine! But when i need to give XPATH some thing like these (test\"fname"\"first")(0), I do not think native scala XML doesn't support this!
@s.Doe I think Scala's native support for XML was more popular in 2010 than it is now. For example here, Prof. Odersky himself says that "XML literals {...} stick{s} out like a sore thumb". I don't know about scala's XML support that much, but maybe it would be easier to use a separate library that takes XPath much more seriously.
Thanks a lot @Andrey

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.