- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
How to perform modification/insertions to an existing XML sub-tree?
My problem: I have to do modifications of sub-trees in my existing XML tree, like adding child nodes or modifying attributes.
In the "Updates and Queries" chapter of http://burak.emir.googlepages.com/scalaxbook.docbk.html is says that XML nodes are immutable. Does that mean that in any existing XML tree, modification of a sub-tree required a full copy of the entire XML tree?
In the "Updates and Queries" chapter of http://burak.emir.googlepages.com/scalaxbook.docbk.html is says that XML nodes are immutable. Does that mean that in any existing XML tree, modification of a sub-tree required a full copy of the entire XML tree?










Re: How to perform modification/insertions to an existing XML s
On Wed, Jan 7, 2009 at 11:17 PM, Trond Olsen <tolsen77 [at] gmail [dot] com> wrote:
No, it requires a copy from the modified node to the root node. This is an O(log n) operation.
--
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
Re: How to perform modification/insertions to an existing XML s
Doesn't "DOM" manipulation of Scala's XML become very verbose when xml sub-trees get passed into other functions and you need to track changes for the root node?
On Thu, Jan 8, 2009 at 3:58 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Re: How to perform modification/insertions to an existing XML s
On Thu, Jan 8, 2009 at 6:57 PM, Trond Olsen <tolsen77 [at] gmail [dot] com> wrote:
No. There's a package that allows you to transform Scala XML documents. It's rather concise, especially with pattern matching. You don't do any of the work, the work is done for you. You just identify the nodes to be changes (old -> new) and everything else is done for you.
Thanks,
David
--
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
Re: How to perform modification/insertions to an existing XML s
A quick example of what I was thinking about:
import scala.xml
def test()
{
val xmlBooks =
<books instruction="update">
<book instruction="remove" name="book1" status=""/>
<book instruction="add" name="book2" status=""/>
</books>
books(xmlBooks)
// How do I get the updated xml here?
}
def books(xmlBooks: xml.Elem)
{
if ((xmlBooks \ "@instruction").text == "update")
{
for (xmlBook <- xmlBooks if (xmlBook \ "@instruction").isEmpty == false)
book(xmlBook)
}
}
def book(xmlBook: xml.Elem)
{
(xmlBook \ "@instruction") match
{
case "add" => {
// Update status attribute for this xml entry.
// Add another xml entry.
}
case "remove" => {
// Remove this xml entry.
}
}
}
For me to make changes in book(), wouldn't that require addional changes to books() and test()?
On Fri, Jan 9, 2009 at 4:41 AM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Re: How to perform modification/insertions to an existing XML s
def test()
{
val xmlBooks =
<books instruction="update">
<book instruction="remove" name="book1" status=""/>
<book instruction="add" name="book2" status=""/>
</books>
books(xmlBooks)
// How do I get the updated xml here?
}
def books(xmlBooks: xml.Elem)
{
if ((xmlBooks \ "@instruction").text == "update")
{
for (xmlBook <- xmlBooks if (xmlBook \ "@instruction").isEmpty == false)
{
(xmlBook \ "@instruction").text match
{
case "remove" => // Remove this xml entry
case _ => book(xmlBook)
}
}
}
}
def book(xmlBook: xml.Elem)
{
(xmlBook \ "@instruction").text match
{
case "add" => {
// Update status attribute for this xml entry.
}
}
}
On Fri, Jan 9, 2009 at 5:23 AM, Trond Olsen <tolsen77 [at] gmail [dot] com> wrote:
Re: How to perform modification/insertions to an existing XML s
You cannot change an immutable data structure. You must return a transformed version of the data structure from a method. In the event of a potential logical failure (there is none in this case), the return type from your method would be Option[T] (where T is the type of the thing). If there's a logic failure, you'll return None. If there's no logical failure, you'll return Some(transformed value).
Also, there's no "for loop" in Scala. There's a "for comprehension." While it may seem to be word games, the conceptual difference between Java's flow of control oriented "for loop" and Scala's transformation oriented "for comprehension" is huge. More on that in another post, although you can get a flavor of what I'm talking about at: http://blog.lostlake.org/index.php?/archives/50-The-Scala-Option-class-and-how-lift-uses-it.html
In terms of your code, here's a working Scala sample. Note, there are no looping constructs. You declare rules for transforming nodes into other nodes and those rules are applied to an XML object.
I hope this helps you understand a bit more of the immutable approach.
Thanks,
David
import scala.xml._
import scala.xml.transform._
def test(): NodeSeq = {
val xmlBooks =
<books instruction="update">
<book instruction="remove" name="book1" status=""/>
<book instruction="add" name="book2" status=""/>
</books>
books(xmlBooks)
}
def books(xmlBooks: Elem): NodeSeq = {
val removeIt = new RewriteRule {
override def transform(n: Node): NodeSeq = n match {
case e: Elem if (e \ "@instruction").text == "remove" =>
NodeSeq.Empty
case n => n
}
}
val addIt = new RewriteRule {
override def transform(n: Node): NodeSeq = n match {
case e: Elem if (e \ "@instruction").text == "add" =>
new Elem(e.prefix, e.label,
e.attributes.remove("instruction"),
e.scope,
transform(e.child) ++ <added>I added this</added> :_*)
case n => n
}
}
val transformer = new RuleTransformer(removeIt , addIt)
transformer.transform(xmlBooks)
}
println(test())
On Thu, Jan 8, 2009 at 8:38 PM, Trond Olsen <tolsen77 [at] gmail [dot] com> wrote:
--
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
Re: How to perform modification/insertions to an existing XML s
On Fri, Jan 9, 2009 at 7:08 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Re: How to perform modification/insertions to an existing XML s
On Fri, Jan 9, 2009 at 5:38 AM, Trond Olsen <tolsen77 [at] gmail [dot] com> wrote:
--
Viktor Klang
Senior Systems Analyst
Re: How to perform modification/insertions to an existing XML s
On Fri, Jan 9, 2009 at 9:31 AM, Viktor Klang <viktor [dot] klang [at] gmail [dot] com> wrote: