用升力将xml转换为Json表现得很奇怪

时间:2021-11-29 23:11:35

I'm using scala / lift for a Rest API. Under the hood I'm generating xml which will be converted to json via Xml.toJson() as output.

我正在使用scala / lift作为Rest API。在引擎盖下,我正在生成xml,它将通过Xml.toJson()转换为json作为输出。

Now i noticed some strange behavior which drives me nuts.

现在我注意到一些奇怪的行为让我疯狂。

for example i have the following xml:

例如,我有以下xml:

<data>
<item>
    <foo>1</foo>
    <bar>1</bar>
</item>
<item>
    <foo>2</foo>
    <bar>2</bar>
</item>
</data>

the result of xml.toJson() looks like:

xml.toJson()的结果如下所示:

JObject(
List(
    JField(
        data,JObject(
            List(
                JField(item,
                JArray(
                    List(
                        JObject(
                            List(
                            JField(foo,JString(1)), 
                            JField(bar,JString(1)))
                        ), 
                        JObject(
                            List(
                            JField(foo,JString(2)), 
                            JField(bar,JString(2))
                            )
                        )
                    )
                )
                )
            )
        )
    )
)
)

but if i add a new xml element:

但如果我添加一个新的xml元素:

<data>
<baz>234</baz>
<item>
    <foo>1</foo>
    <bar>1</bar>
</item>
<item>
    <foo>2</foo>
    <bar>2</bar>
</item>
</data>

the result is different regarding the JArray:

关于JArray的结果是不同的:

JObject(
List(
    JField(data,JObject(
        List(
            JField(baz,JString(234)), 
            JField(item,JObject(
                List(
                    JField(foo,JString(1)), 
                    JField(bar,JString(1))
                ))
            ), 
            JField(item,JObject(
                List(
                    JField(foo,JString(2)), 
                    JField(bar,JString(2))
                ))
            )
        )
    ))
)

)

The array isn't defined and i have two objects with the name "item". Is this a normal behavior? I would like to have the array without wrapping someting aroung the "item" Tags.

数组未定义,我有两个名为“item”的对象。这是正常行为吗?我想让数组没有包装一些“项目”标签。

1 个解决方案

#1


5  

Yep, this is the intended behavior: net.liftweb.json.Xml will only group child elements into a JArray if they all have the same name. You can try to get around this behavior by manipulating the generated JSON:

是的,这是预期的行为:net.liftweb.json.Xml只会将子元素组合成JArray,如果它们都具有相同的名称。您可以尝试通过操纵生成的JSON来解决此问题:

JObject(
  (json \ "data").asInstanceOf[JObject].obj.groupBy(_.name).map {
    case (_, v :: Nil) => v
    case (k, vs)       => JField(k, JArray(vs.map(_.value)))
  }.toList
)

But there are at least a couple of potential problems here:

但这里至少存在一些潜在的问题:

  1. We're using groupBy, so we may end up rearranging the order of child elements.
  2. 我们正在使用groupBy,因此我们最终可能会重新排列子元素的顺序。

  3. If there's only one item, it won't get wrapped in a JArray.
  4. 如果只有一个项目,它将不会被包装在JArray中。

Depending on how much you care, you could write your way around these issues, but it's almost certainly not worth it. Just ignore net.liftweb.json.Xml and generate both your XML and your JSON from a Scala data structure.

根据您的关心程度,您可以围绕这些问题编写方法,但几乎肯定不值得。只需忽略net.liftweb.json.Xml并从Scala数据结构生成XML和JSON。

#1


5  

Yep, this is the intended behavior: net.liftweb.json.Xml will only group child elements into a JArray if they all have the same name. You can try to get around this behavior by manipulating the generated JSON:

是的,这是预期的行为:net.liftweb.json.Xml只会将子元素组合成JArray,如果它们都具有相同的名称。您可以尝试通过操纵生成的JSON来解决此问题:

JObject(
  (json \ "data").asInstanceOf[JObject].obj.groupBy(_.name).map {
    case (_, v :: Nil) => v
    case (k, vs)       => JField(k, JArray(vs.map(_.value)))
  }.toList
)

But there are at least a couple of potential problems here:

但这里至少存在一些潜在的问题:

  1. We're using groupBy, so we may end up rearranging the order of child elements.
  2. 我们正在使用groupBy,因此我们最终可能会重新排列子元素的顺序。

  3. If there's only one item, it won't get wrapped in a JArray.
  4. 如果只有一个项目,它将不会被包装在JArray中。

Depending on how much you care, you could write your way around these issues, but it's almost certainly not worth it. Just ignore net.liftweb.json.Xml and generate both your XML and your JSON from a Scala data structure.

根据您的关心程度,您可以围绕这些问题编写方法,但几乎肯定不值得。只需忽略net.liftweb.json.Xml并从Scala数据结构生成XML和JSON。