About the return type of evaluate method

33 views
Skip to first unread message

Toshihiko Makita

unread,
Oct 7, 2013, 8:20:12 AM10/7/13
to scale...@googlegroups.com
Dear Chris,

Please allow me to submit a newbie question to Scales XML. 

My question is about the return type of evaluate method in ScalesXPath class.

1. Why do you adopt Either[AttributePath, XmlPath] for the return type of evaluate?

I felt that it is inconvenient to select right or left according to the XPath expression. For instance, when I write following XPath expression, I must use right.get to obtain the string value.

val doc =  loadXml(new java.io.FileReader("MusicLibrary.xml"),defaultPathOptimisation)
val root = top(doc)
val xpath = ScalesXPath("/musicLibrary/cd[string(year) = '1994']/title")
val title = xpath.evaluate(root).head
println("The title='" + string(title.right.get) + "'")

If I write the following XPath expression, I must use left.get in the same way.

val doc =  loadXml(new java.io.FileReader("MusicLibrary.xml"),defaultPathOptimisation)
val root = top(doc)
val xpath = ScalesXPath("/musicLibrary/cd[1]/@id")
val attr = xpath.evaluate(root).head
println("The attr @id='" + string(attr.left.get) + "'")

I think that Either class is not easy to use from the library user's perspective.

2. XPath sometimes returns the atomic value.

Following XPath expression causes run-time error.

val xpath = ScalesXPath("count(/musicLibrary/cd)")
val value = xpath.evaluate(root)
println("The value='" + value.toString() + "'")

Exception in thread "main" scala.MatchError: 5.0 (of class java.lang.Double)
at scales.xml.jaxen.ScalesXPath.evaluate(JaxenNavigator.scala:121)
at xmltest.main2$.main(main2.scala:31)
at xmltest.main2.main(main2.scala)

val xpath = ScalesXPath("string(/musicLibrary/cd[1])")
val result = xpath.evaluate(root).head
println("The result='" + result.toString() + "'")

Exception in thread "main" scala.MatchError: 
    Parallel Lines
    2001
    Blondie
    New Wave
   (of class java.lang.String)
at scales.xml.jaxen.ScalesXPath.evaluate(JaxenNavigator.scala:121)
at xmltest.main2$.main(main2.scala:36)
at xmltest.main2.main(main2.scala)

Do you have a plan to support these XPath expression in Scales XML?

For your reference .net System.Xml.XPath supports the following methods (This is F# notation).

static member XPathEvaluate : 
        node:XNode * 
        expression:string -> Object

It returns System.Object. In paticular the return type is one of bool, double, string or IEnumerable(T). 

static member XPathSelectElements : 
        node:XNode * 
        expression:string -> IEnumerable<XElement> 

This method selects sequence of elements.

static member XPathSelectElement : 
        node:XNode * 
        expression:string -> XElement 

This method selects one element.

I think above interfaces are very reasonable for the user who use the XPath expression in program. 

Regards,

Chris Twiner

unread,
Oct 8, 2013, 2:42:24 AM10/8/13
to scale...@googlegroups.com

Hiya,

http://scala-scales.googlecode.com/svn/sites/scales/scales-xml_2.9.2/0.4.4/StringXPaths.html

Shows examples for each of your requests.

The remaining question of why an Either is interesting! 

The reason is non atomic values can be either an attribute or an element.  Using Either forces the user to consider that choice.

Because Jaxen allows us to return any object from a custom function we can only default to object for atomics.

As such I split atomics from sequence evaluations.

Under XPath 2 a triple choice would be present, either XPath, AttributePath or AnyRef.

Hth to understand a bit of the background.

Cheers,
Chris

--
You received this message because you are subscribed to the Google Groups "scales-xml" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scales-xml+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages