lift-Json doesn't appear to be correctly handling attributes.

19 views
Skip to first unread message

Jonathan Ferguson

unread,
Feb 2, 2010, 8:41:15 PM2/2/10
to lif...@googlegroups.com

When converting XML to Json attributes are being lost, given the below XML document, we would expect 
{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}
where as we get {"word":"content"} 
example XML: 
<word term="example" self="http://localhost:8080/word/example" available="true">content</word>

This is been tested on M1 and trunk.

Thanks in advance. 

To repeat

// From the command line, adjust paths as needed

$scala -cp /Users/jono/.m2/repository/com/thoughtworks/paranamer/paranamer/2.0/paranamer-2.0.jar:/Users/jono/.m2/repository/net/liftweb/lift-json/2.0-SNAPSHOT/lift-json-2.0-SNAPSHOT.jar

import scala.xml._
import net.liftweb.json.JsonAST._
import net.liftweb.json.Printer
import net.liftweb.json.Xml

val example1 = <word term="example" self="http://localhost:8080/word/example" available="true">content</word>
val expected1 = """{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}"""
val got1 = Printer.compact(render(Xml.toJson(example1)))


val example2 = <word term="example" self="http://localhost:8080/word/example" available="true"></word>
val expected2 = """{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}"""
val got2 = Printer.compact(render(Xml.toJson(example2)))


// Add to src/test/scala/net/liftweb/json/XmlBugs.scala

  "Jono's XML with attributes parses correctly" in {
val example1 = <word term="example" self="http://localhost:8080/word/example" available="true">content</word>
val expected1 = """{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}"""

val example2 = <word term="example" self="http://localhost:8080/word/example" available="true"></word>
val expected2 = """{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}"""
  
    Printer.compact(render(toJson(example1))) mustEqual expected1
    Printer.compact(render(toJson(example2))) mustEqual expected2
  }


Here is what I get when I run the example provided.


$scala -cp /Users/jono/.m2/repository/com/thoughtworks/paranamer/paranamer/2.0/paranamer-2.0.jar:/Users/jono/.m2/repository/net/liftweb/lift-json/2.0-SNAPSHOT/lift-json-2.0-SNAPSHOT.jar
Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.xml._
import scala.xml._

scala> import net.liftweb.json.JsonAST._
import net.liftweb.json.JsonAST._

scala> import net.liftweb.json.Printer
import net.liftweb.json.Printer

scala> import net.liftweb.json.Xml
import net.liftweb.json.Xml

scala> 

scala> val example1 = <word term="example" self="http://localhost:8080/word/example" available="true">content</word>
example1: scala.xml.Elem = <word self="http://localhost:8080/word/example" term="example" available="true">content</word>

scala> val expected1 = """{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}"""
expected1: java.lang.String = {"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}

scala> val got1 = Printer.compact(render(Xml.toJson(example1)))
got1: String = {"word":"content"}

scala> 


Jono

P.S I thought I had a fix, but it broke one of HarryH's tests.



scala> 

scala> val example2 = <word term="example" self="http://localhost:8080/word/example" available="true"></word>
example2: scala.xml.Elem = <word self="http://localhost:8080/word/example" term="example" available="true"></word>

scala> val expected2 = """{"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}"""
expected2: java.lang.String = {"word":{"word":"content","self":"http://localhost:8080/word/example","term":"example","available":"true"}}

scala> val got2 = Printer.compact(render(Xml.toJson(example2)))
got2: String = {"word":null}

scala> 

Joni Freeman

unread,
Feb 3, 2010, 1:46:35 AM2/3/10
to Lift
Hi Jonathan,

Yes, definitely a bug. Could you please open a ticket (http://
github.com/dpp/liftweb/issues) and I will take a look at it. And
thanks for the test case!

Cheers Joni

Jonathan Ferguson

unread,
Feb 3, 2010, 4:31:42 PM2/3/10
to lif...@googlegroups.com
Thanks Joni, 


Cheers 
Jono

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.


Joni Freeman

unread,
Feb 4, 2010, 4:54:39 AM2/4/10
to Lift
Thanks,

The fix is on review board now. Should be in master pretty soon. Note,
I made two changes to the test case you provided.

The expected result of example1 is:


{"word":"content","self":"http://localhost:8080/word/

example","term":"example","available":"true"}

The transformation converts XML attributes to fields in resulting JSON
object. The reason for this rule is that it keeps transformation more
"stable". That is, these both will generate structurally equivalent
JSON:
<word>foo</word> -> {"word":"foo"}
<word attr="bar">foo</word> -> {"word":"foo","attr":"bar"}

The expected result of example2 is:
{"word":null,"self":"http://localhost:8080/word/
example","term":"example","available":"true"}

Field "word" is null since there's no content: <word ...></word>

Cheers Joni


On Feb 3, 11:31 pm, Jonathan Ferguson <j...@spiralarm.com> wrote:
> Thanks Joni,
>
> I've opened a ticket  http://github.com/dpp/liftweb/issues/issue/323.
>
> Cheers
> Jono
>

> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com>

Reply all
Reply to author
Forward
0 new messages