Thanks for the update Joni and sorry for not getting back sooner. I'll try
the code change you've suggested. Should I open a bug for the final example?

Cheers

Jono


2009/10/28 Joni Freeman <freeman.j...@gmail.com>

>
> Hi Jonathan,
>
> Current toJson conversion does not support this case very well. The
> transformation rule is such that from each leaf XML element a JSON
> field is generated.
>
> <stats>foo</stats> ->
> "stats":"foo"
>
> And if that leaf element contains attributes we do not convert it
> automatically to JSON object as you expected. Instead, another field
> at same level is created:
>
> <stats count="0">foo</stats> ->
> "stats":"foo"
> "count":"0"
>
> In your case the leaf node is empty, therefore you will get a field
> with null value:
>
> <stats count="0"></stats> ->
> "stats":null
> "count":"0"
>
> You can fix this for instance by postprocessing the generated JSON. In
> this case it is a bit involved and verbose (example below fixes
> 'stats' element, similar conversion is required for 'messages'
> element):
>
> val json = toJson(xml1) map {
>  case JField("count", JString(count)) => JObject(JField("count", JInt
> (count.toInt)) :: Nil) // lift to object
>  case JField("stats", _) => JNothing // remove null field
>  case x => x
> } map {
>  case JField("count", x: JObject) => JField("stats", x) // rename
> field "count" to "stats"
>  case x => x
> }
>
> Note, the conversion rule which you expected is a perfectly valid
> conversion too. The rationale behind the current rule is that it never
> makes conversions which changes resulting JSON structure when
> attributes are missing. It is therefore more predictable. This blog
> post summarizes some other valid conversion rules
> http://onwebdevelopment.blogspot.com/2008/05/converting-xml-to-json.html
>
> We could add support for other conversion rules if there's a strong
> pressure to do so. But my current preference is to use a simple rule
> and then handle corner cases using transformation pipelines (using
> 'map' function).
>
> PS. The very last example you gave contains a bug which I try to nail
> down today. XML is parsed differently when all elements are in same
> line. Thanks for good examples!
>
> Cheers Joni
>
> On 28 loka, 09:24, Jonathan Ferguson <j...@spiralarm.com> wrote:
> > Depending on the structure of the XML, attributes and child elements
> > are being lost. This can be seen in example 4, where the attribute
> > expiry_date and the child element status have been dropped.
> >
> > It would also appear when XML is being converted to JSON attributes
> > are being flattened to elements. I'm not sure if this is expected or
> > not, this can be seen in examples  1,2 & 3. The child
> > element status with attribute count is converted to two attributes
> > status with a value of null and count with the correct value.
> >
> > To test I added the following before the closing brace of
> > XmlExamplesTest.scala in lift-json.
> >
> > Is this a bug or my error ?
> >
> > Cheers
> > Jono
> >
> > P.S I've noticed this could be related to the thread "Possible lift-
> > json bug in Xml.toJson"
> http://groups.google.com/group/liftweb/browse_thread/thread/47c581d63...
> >
> > /*==== Test  ====*/
> >
> >   import scala.xml.Node
> >
> >  def xml2Json(xml:Node):String = {
> >     val json = toJson(xml)
> >     compact(render(json))
> >   }
> >
> >   "XML to JSON Example with multiple attributes, multiple nested
> > elements " in  {  xml2Json(xml1) mustEqual expected1 }
> >   "XML to JSON Example with multiple attributes, multiple nested
> > elements "  in  {  xml2Json(xml2) mustEqual expected2 }
> >   "XML to JSON Example with one attribute,  multiple nested elements
> > " in  {  xml2Json(xml3) mustEqual expected3 }
> >   "XML to JSON Example with one attribute, one nested element " in
> > {  xml2Json(xml4) mustEqual expected4 }
> >
> > val xml1         = <message expiry_date="20091126" text="text"
> > word="ant" self="me"><stats count="0"></stats><messages href="https://
> > domain.com/message/ant"></messages></message>
> > val expected1 = """{"message":{"expiry_date":
> > 20091126,"text":"text","word":"ant","self":"me","stats":{"count":
> > 0},"messages":{"href":"https://domain.com/message/ant"}}}""";
> > val actual1     = """{"message":
> >
> {"expiry_date":"20091126","word":"ant","text":"text","self":"me","stats":null,"count":"0","messages":null,"href":"https://
> > domain.com/message/ant"}}"""
> >
> > val xml2         = <message expiry_date="20091126" text="text"
> > word="ant" self="me"><stats count="0"></stats><messages href="https://
> > domain.com/message/ant"></messages></message>
> > val expected2 = """{"message":{"expiry_date":
> > 20091126,"text":"text","word":"ant","self":"me","stats":{"count":
> > 0},"messages":{"href":"https://domain.com/message/ant"}}}""";
> > val actual2      = """{"message":
> >
> {"expiry_date":"20091126","word":"ant","text":"text","self":"me","stats":null,"count":"0","messages":null,"href":"https://
> > domain.com/message/ant"}}"""
> >
> > val xml3          = <message expiry_date="20091126"><stats count="0"></
> > stats><messages href="https://domain.com/message/ant";></messages></
> > message>
> > val expected3  = """{"message":{"expiry_date":20091126,"stats":
> > {"count":0},"messages":{"href":"https://domain.com/message/ant"}}}""";
> > val actual3      = """{"message":
> >
> {"expiry_date":"20091126","stats":null,"count":"0","messages":null,"href":"https://
> > domain.com/message/ant"}}"""
> >
> > val xml4          = <message expiry_date="20091126"><stats count="0"></
> > stats></message>
> > val expected4  = """{"message":{"expiry_date":20091126,"stats":
> > {"count":0}}}"""
> > val actual4      = """{"message":""}"""
> >
>

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

Reply via email to