【问题标题】:Scala XML serializationScala XML 序列化
【发布时间】:2010-10-19 20:53:45
【问题描述】:

看到 Scala 的强大功能,我想知道是否可以使用内置的 Scala 语言功能和库(例如,不使用 XMLEncoder、XStream 或 JAXB)对任意对象图进行序列化和反序列化到 XML 或从 XML 反序列化。不幸的是,我还没有找到这样的解决方案。你有什么建议?

【问题讨论】:

    标签: xml serialization scala


    【解决方案1】:

    afaik 没有这样的事情。不过你可能想看看sbinary

    【讨论】:

      【解决方案2】:

      Scala 的本机类库中没有任何内容。但是不乏能够做到这一点的 Java 库。

      【讨论】:

        【解决方案3】:

        就“建议”而言,我们一直在使用本地库来处理许多简单粗暴的配置文件。主要优点是“解析”代码用于添加漂亮的错误消息。像这样:

        val xml = xml.XML.load( source )
        
        val required = ( xml \ "value" ).firstOption match {
            case None => error( "The value element is missing, or should I be a default?" )
            case Some( req ) => req
        }
        

        这是我通常使用 XStream 之类的东西的地方,所以它不是一个大开关。我不确定您是否可以使用库在反序列化框架上获得错误消息 + 默认处理。

        【讨论】:

          【解决方案4】:

          我不知道“是否可以使用内置的 Scala 语言功能和库对任意对象图进行序列化和反序列化到 XML 或从 XML 反序列化”,但由于 Scala 中有一些对 XML 的本机支持,所以我会提到他们。更多细节可以在 Ch 中找到。 Programming in Scala 中的 26 个称为使用 XML:

          本章介绍了 Scala 的 支持 XML。讨论后 一般来说,半结构化数据 显示了基本功能 用于操作 XML 的 Scala:如何 使用 XML 文字制作节点,如何 保存和加载 XML 到文件,以及如何 使用查询拆分 XML 节点 方法和模式匹配。

          为了快速总结本章,我将引用一些关键点。

          • Scala 包括对处理 XML 的特殊支持。
          • Scala 允许您在表达式有效的任何地方输入 XML 作为文字。
          • 您可以使用花括号 ({}) 作为转义符来评估 XML 文字中间的 Scala 代码。

          所以你可以这样写:

          val foo = <a> {3 + 4} </a>
          

          以上计算结果为scala.xml.Elem = &lt;a&gt; 7 &lt;/a&gt;

          • 如果您想通过标签名称查找子元素,只需使用标签名称调用\
          • 您可以使用\\ 而不是\ 运算符进行“深度搜索”并查看子子元素等。

          书中有一个抽象类的序列化和反序列化的例子,但是是手写的:

          abstract class CCTherm {
            val description: String
            val yearMade: Int
          
            def toXML =
              <cctherm>
                <description>{description}</description>
                <yearMade>{yearMade}</yearMade>
              </cctherm>
          
            def fromXML(node: scala.xml.Node): CCTherm =
              new CCTherm {
                val description = (node \ "description").text
                val yearMade    = (node \ "yearMade").text.toInt
              }    
          }
          

          还可以在名为scala.xml 的草稿书中找到更多信息。

          【讨论】:

          • 感谢您的详细回答。不过,我想要一个通用的解决方案,其中序列化代码只编写一次,而不是在每个类中,以避免样板代码和信息重复。
          • 对于那些有本书第2版的人,XML章节是第28章。
          【解决方案5】:

          在包net.liftweb.json,object xml中,找到如下函数:

          def toXml(json: JValue): NodeSeq = {
              def toXml(name: String, json: JValue): NodeSeq = json match {
                case JObject(fields) => new XmlNode(name, fields flatMap { f => toXml(f.name, f.value) })
                case JArray(xs) => xs flatMap { v => toXml(name, v) }
                case JField(n, v) => new XmlNode(name, toXml(n, v))
                case JInt(x) => new XmlElem(name, x.toString)
                case JDouble(x) => new XmlElem(name, x.toString)
                case JString(x) => new XmlElem(name, x)
                case JBool(x) => new XmlElem(name, x.toString)
                case JNull => new XmlElem(name, "null")
                case JNothing => Text("")
              }
          
              json match {
                case JField(n, v) => toXml(n, v)
                case JObject(fields) => fields flatMap { f => toXml(f.name, f.value) }
                case x => toXml("root", x)
              }
            }
          

          有一个提取包,它具有将至少案例类转换为 JSON 的功能。与 toXml 一起,这可能会将许多数据类型转换为 XML。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-01-21
            • 2012-09-17
            • 1970-01-01
            • 2011-05-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多