微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

例如,我有以下xml:

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

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)),JString(2))
                            )
                        )
                    )
                )
                )
            )
        )
    )
)
)

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

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

关于JArray的结果是不同的:

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

)

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

解决方法

是的,这是预期的行为: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
)

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

>我们正在使用groupBy,因此我们最终可能会重新排列
儿童元素.
>如果只有一个项目,它将不会被包装在JArray中.

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。