【问题标题】:Convert complex Scala XML with namespaces and properties to Scala objects将具有命名空间和属性的复杂 Scala XML 转换为 Scala 对象
【发布时间】:2013-05-15 20:21:28
【问题描述】:

将普通的 Scala XML 转换为对象似乎很容易:

<object><field>1</field></object> 可以使用案例类 Object( field: Int ) 和 Scala 的原生 XML API 创建类似 Object(1) 的内容。

但是如果 XML 包含命名空间和属性呢?比如ATOM格式?

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:service="http://activitystrea.ms/service-provider" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:gnip="http://www.gnip.com/schemas/2010">
<id>456520791711374025_380135597</id>
<published>2013-05-15T18:12:20Z</published>
<source>
<link rel="self" type="application/json" href="https://url.com/v1/tags/taghere/media/recent?client_id=xxxxxxxxxxx"/>
<updated>2013-05-15T18-12-43Z</updated>
<gnip:rule xmlns:gnip="http://www.gnip.com/schemas/2010">rulehere</gnip:rule>
</source>
<service:provider>
<name>Provider</name>
<uri>www.url.com</uri>
</service:provider>
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
<activity:object>
<activity:object-type>http://activitystrea.ms/schema/1.0/image</activity:object-type>
<gnip:statistics favoriteCount="0"/>
</activity:object>
</entry>

【问题讨论】:

    标签: xml scala xml-parsing xml-serialization


    【解决方案1】:

    处理更复杂的 XML 格式需要特定类的高级注释。推荐的策略是使用 JAXB 之类的东西来注释类中的每个字段。

    这里是改编自http://krasserm.blogspot.ca/2012/02/using-jaxb-for-xml-and-json-apis-in.html的一些示例代码:

    import scala.annotation.meta.field 
    
    //Scala 2.9 or lower uses scala.annotation.target.field
     
    import javax.xml.bind.annotation._
    import javax.xml.bind.annotation.adapters._
     
    type xmlElement     = XmlElement @field
    type xmlTypeAdapter = XmlJavaTypeAdapter @field
     
    class StringOptionAdapter extends OptionAdapter[String](null, "")
    class OptionAdapter[A](nones: A*) extends XmlAdapter[A, Option[A]] {
      def marshal(v: Option[A]): A = v.getOrElse(nones(0))
      def unmarshal(v: A) = if (nones contains v) None else Some(v)
    }
     
    @XmlRootElement(name = "person")
    @XmlAccessorType(XmlAccessType.FIELD)
    case class Person(
        @xmlElement(required=true) fullname: String, 
        @xmlTypeAdapter(classOf[StringOptionAdapter]) username: Option[String], 
        age: Int) {
      // only needed and accessed by JAXB
      private def this() = this("", None, 0)
    }
    

    请注意,案例类要求您针对特定字段,因此要导入 annotation.meta.field

    仅供参考,您可以在此处添加 JAXB 作为依赖项:http://search.maven.org/#artifactdetails%7Cjavax.xml.bind%7Cjaxb-api%7C2.2.9%7Cjar

    编辑

    虽然我个人不喜欢它,但也可以通过scalaxb 获得 Xml 支持。它作为本机插件工作,不一定充当典型的 Maven 依赖项。它使用 XML 模板等高级功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      • 2014-04-04
      • 1970-01-01
      • 2012-03-24
      相关资源
      最近更新 更多