This page is no longer maintained — Please continue to the home page at www.scala-lang.org

XPath vs Scala ML

5 replies
sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.

I'm finding Scala's built-in XML problematic. I want to write the equivalent
of the following XPath:

things/thing[@id="123"]

Looks simple enough, and it's something I do all the time. The Scala
equivalent I ended up with looks something like this:

val nodes = doc \ "things" \ "thing" filter(n => Integer.parseInt((n \
"@id").text) == id)

...but that throws an exception when it encounters a without an id
attribute, so to handle it properly would need even more long-winded
checking:

val nodes = file \ "things" \ "thing" filter {n =>
val attribute = n \ "@id" text
attribute match {
case "" => false
case _ => Integer.parseInt((n \ "@id").text) == id
}
}

...or something like that. I attempted to do it with pattern-matching
instead:

val nodes = file \ "amvs" \ "amv" filter (n => n match {
case
_*
=> true
case _ => false
})

...but it didn't like me putting attributes in XML patterns. What should be
a very simple query is now getting out of hand, and I'm left feeling like
I'm missing something.

My ideal solution would simply to use the XPath in place of the element name
like so:

val nodes = doc \ "things" \ "thing[@id={id}]"

Not only is that shorter, but it's clever enough to reject any
elements without a matching attribute. I know Scala can't really support the
whole of XPath because it's functional, immutable XML trees don't have
parent information. But it would be damned useful if it supported a
rudimentary subset, making straightforward queries like this easier.

Could an implicit conversion make something like this happen, without
introducing too much freaky syntax?

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: XPath vs Scala ML
def toInt(in: String): Option[Int] = try {Some(in.toInt)} catch {case _ => None}

doc \ "things" \ "thing" \ filter(n => toInt((n \ "@id").text) == Some(id)))



On Mon, Dec 22, 2008 at 4:47 PM, sadie <marcus [at] minotaur [dot] it> wrote:

I'm finding Scala's built-in XML problematic. I want to write the equivalent
of the following XPath:

   things/thing[@id="123"]

Looks simple enough, and it's something I do all the time. The Scala
equivalent I ended up with looks something like this:

   val nodes = doc \ "things" \ "thing" filter(n => Integer.parseInt((n \
"@id").text) == id)

...but that throws an exception when it encounters a <thing> without an id
attribute, so to handle it properly would need even more long-winded
checking:

   val nodes = file \ "things" \ "thing" filter {n =>
       val attribute = n \ "@id" text
       attribute match {
           case "" => false
           case _ => Integer.parseInt((n \ "@id").text) == id
       }
   }

...or something like that. I attempted to do it with pattern-matching
instead:


   val nodes = file \ "amvs" \ "amv" filter (n => n match {
           case <amv id="1">
                   _*
                </amv> => true
           case _ => false
       })

...but it didn't like me putting attributes in XML patterns. What should be
a very simple query is now getting out of hand, and I'm left feeling like
I'm missing something.

My ideal solution would simply to use the XPath in place of the element name
like so:

   val nodes = doc \ "things" \ "thing[@id={id}]"

Not only is that shorter, but it's clever enough to reject any <thing>
elements without a matching attribute. I know Scala can't really support the
whole of XPath because it's functional, immutable XML trees don't have
parent information. But it would be damned useful if it supported a
rudimentary subset, making straightforward queries like this easier.

Could an implicit conversion make something like this happen, without
introducing too much freaky syntax?
--
View this message in context: http://www.nabble.com/XPath-vs-Scala-ML-tp21137764p21137764.html
Sent from the Scala - User mailing list archive at Nabble.com.




--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: XPath vs Scala ML

David Pollak-4 wrote:
>
> def toInt(in: String): Option[Int] = try {Some(in.toInt)} catch {case _ =>
> None}
>
> doc \ "things" \ "thing" \ filter(n => toInt((n \ "@id").text) ==
> Some(id)))
>
That solves my immediate problem, thank you - and it demonstrates some of
what's so nice about Scala. But I still think there needs to be something
closer to real XPath available in Scala.xml:

1. The semantics of the code above is not identical to that of the XPath -
for example, it cannot tell the difference between and . Granted that isn't relevant this time.

2. Not all cases are going to be as simple as my dummy example, and using
the filter(n=>...) syntax for each test in a complex path will get
annoyingly long-winded.

3. XPath is a standard. People are going to have legacy XPaths they wish to
keep using, or will find the inability to use their existing skills a
barrier to entry.

Martin S. Weber
Joined: 2008-12-23,
User offline. Last seen 42 years 45 weeks ago.
Re: XPath vs Scala ML

Quoting sadie :
> 3. XPath is a standard. People are going to have legacy XPaths they wish to
> keep using, or will find the inability to use their existing skills a
> barrier to entry.

..which is why I'll be focussing on contributing "standards" support
in (pure as much as possible) scala once I'm finished with my current
scala/swing application (which though begs me to contribute on the
swing part instead -hum-). I think the same way. XPath expressions
must be allowed in match positions (i.e. there should be an xpath
class/companion with a fitting unapply/unappseq method etc). Scala's
interpretation of / and // to \ and \\ are interesting but do not
scale at all *imo* (i.e. are nice on toy examples but not on big /
real-life / industry ones). Non-namespaced xml literals in match
position are another thing. (...which are important enough to me to
want to have them and as my current employer pays me to put work into
persuading them to change their ways I want to contribute as much as
possible in the areas where I think scala/xml needs to be extended so
I can - with good conscience - persuade my employer of going scala.)

If someone beats me to it, the better, less work for me :)

-Martin

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: XPath vs Scala ML


On Mon, Dec 22, 2008 at 5:26 PM, sadie <marcus [at] minotaur [dot] it> wrote:


David Pollak-4 wrote:
>
> def toInt(in: String): Option[Int] = try {Some(in.toInt)} catch {case _ =>
> None}
>
> doc \ "things" \ "thing" \ filter(n => toInt((n \ "@id").text) ==
> Some(id)))
>
That solves my immediate problem, thank you - and it demonstrates some of
what's so nice about Scala. But I still think there needs to be something
closer to real XPath available in Scala.xml:

1. The semantics of the code above is not identical to that of the XPath -
for example, it cannot tell the difference between <thing> and <thing
id="">. Granted that isn't relevant this time.

2. Not all cases are going to be as simple as my dummy example, and using
the filter(n=>...) syntax for each test in a complex path will get
annoyingly long-winded.

I think you'll find the for comprehension works well in this instance.
 


3. XPath is a standard. People are going to have legacy XPaths they wish to
keep using, or will find the inability to use their existing skills a
barrier to entry.

And you can use all the Java XPath stuff in Scala.

Thanks,

David

--
View this message in context: http://www.nabble.com/XPath-vs-Scala-ML-tp21137764p21138106.html
Sent from the Scala - User mailing list archive at Nabble.com.




--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Erkki Lindpere
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
Re: XPath vs Scala ML

How about this (not tested):

val nodes = doc \ "things" \ "thing" filter(n => id.toString == (n \
"@id" text))

But yeah, I agree that there should be better support for XPath.

Erkki

sadie wrote:
> things/thing[@id="123"]
>
> val nodes = doc \ "things" \ "thing" filter(n => Integer.parseInt((n \
> "@id").text) == id)
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland