Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用lift将xml转换为Json的行为很奇怪_Xml_Json_Scala_Xml Serialization_Lift - Fatal编程技术网

使用lift将xml转换为Json的行为很奇怪

使用lift将xml转换为Json的行为很奇怪,xml,json,scala,xml-serialization,lift,Xml,Json,Scala,Xml Serialization,Lift,我正在使用scala/lift作为restapi。在引擎盖下,我正在生成xml,它将通过xml.toJson()作为输出转换为json 现在我注意到一些让我发疯的奇怪行为 例如,我有以下xml: <data> <item> <foo>1</foo> <bar>1</bar> </item> <item> <foo>2</foo> <bar&

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

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

例如,我有以下xml:

<data>
<item>
    <foo>1</foo>
    <bar>1</bar>
</item>
<item>
    <foo>2</foo>
    <bar>2</bar>
</item>
</data>
但如果我添加一个新的xml元素:

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


数组没有定义,我有两个名为“item”的对象。这是正常的行为吗?我希望数组不围绕“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即可。

    您将如何做到这一点?创建一个包含字段的case类,然后对其进行序列化?是的,这将使您能够更好地控制两种序列化格式的表示。请给我一个示例,说明如何从Scala数据结构生成XML和JSON。
    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))
                    ))
                )
            )
        ))
    )
    
    JObject(
      (json \ "data").asInstanceOf[JObject].obj.groupBy(_.name).map {
        case (_, v :: Nil) => v
        case (k, vs)       => JField(k, JArray(vs.map(_.value)))
      }.toList
    )