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

Getting a full XPath from an XML Node

1 reply
Serge Merzliakov
Joined: 2009-03-27,
User offline. Last seen 42 years 45 weeks ago.

Hello,
I am trying to replicate some java functionality which converts XML
elements into Java style properties (e.g. "foo.bar.length"). the following
Java snippet:

XPath all = dom.getRootElement().createXPath("//*");
List< ? > results = all.selectNodes(dom.getRootElement());

using this XML:

hello
red

gives (with some more code not pasted here..) these 2 properties:

goal.name=hello
goal.color=red

I have tried to do this with Scala Xpath's like queries but am having issues
with getting a full XPath from each Node object in "kids" NodeSeq . Here is
my code and am happy for alternative approaches on this.

val xmldoc = XML.loadFile(configFile)
val kids = xmldoc \\ "_"
kids.foreach(child => printXPath(child)) // calls my function

The printXPath function uses Node method descendant_or_self to manually
build XPath

So my question is - How can I get full XPath from an XML Node using Scala.
The only option I can think of is to use the Java XPath libraries (commonly
using Java 6 SDK or Jaxen) in Scala - but I am hoping to find a
Scala-centric solution.

Regards,
Serge

Florian Hars
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Getting a full XPath from an XML Node

Serge Merzliakov schrieb:
> So my question is - How can I get full XPath from an XML Node using Scala.

You have to keep track of the parents while descending into the tree.
Because of the functional architecture of the library, the nodes cannot
know anything about their parents:

scala> val n = bar
n: scala.xml.Elem = bar

scala> {n}
res0: scala.xml.Elem = bar

scala> {n}
res1: scala.xml.Elem = bar

scala> val kidsA = res0 \\ "foo"
kidsA: scala.xml.NodeSeq = bar

scala> val kidsB = res1 \\ "foo"
kidsB: scala.xml.NodeSeq = bar

scala> kidsA equals kidsB
res2: Boolean = true

scala> kidsA eq kidsB
res3: Boolean = false

scala> kidsA(0) eq kidsB(0)
res4: Boolean = true

I.e. the (physically) same node can be part of different trees and
so have different XPaths relative to these trees.

- Florian

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