xml - AntiXML 中的链接转换

标签 xml scala

我有反 xml 元素,像这样(自动生成的数据):

<library>
  <bookshelf number="0">
    <book year="1997" title="Puzzled Coordinators" author="Lily Williams"></book>
    <book year="2005" title="Jittery Fare" author="Lucy Taylor"></book>
    <book year="2001" title="Dizzy Jurisdiction" author="Lucy Robinson"></book>
  </bookshelf>
  <bookshelf number="1">
    <book year="1997" title="Bashful Trusts" author="Lucas Wilson"></book>
    <book year="2003" title="Outrageous Consequences" author="Byron White"></book>
    <book year="1992" title="Irritated Accusations" author="Anne Roberts"></book>
  </bookshelf>
</library>

我想对其应用几个转换,例如:

val transforms: Seq[...] = ...
val result = transforms.foldLeft(library)(l,t) => t(l))

但我只得到了这个解决方案:

val transforms: Seq[Elem => Zipper[Node]] = Seq(
  x => x \\ "book" filter (_.attrs("year").toInt > 2000) unselect,
  x => x \\ "book" filter (_.attrs("title").contains("J")) unselect
)
val result = transforms.foldLeft(lib)((l,t) => t(l).head.asInstanceOf[Elem])

有没有什么方法可以获得更好的转换类型 (Elem => Elem) 并避免那些丑陋的转换?

最佳答案

考虑到 unselect 目前只返回一个 Zipper[Node],我看不出有什么方法可以在不对类型系统进行一些调整的情况下获得你想要的东西,这需要类型转换之类的东西。

在这种情况下,鉴于 Anti-XML 库的当前状态,您确实确实知道类型系统无法知道的事情:您知道转换产生的 zipper 的父级是Zipper[Elem],因此 unselect 给你的实际上是一个 Zipper[Elem],甚至虽然它的类型是 Zipper[Node]

所以我认为你能做的最好的事情就是把不愉快的事情打包得更干净一点:

def toEndo(t: Elem => Zipper[Elem]): Elem => Elem =
  t andThen (_.unselect.head.asInstanceOf[Elem])

或者,为了让您的意图更加明显:

def toEndo(t: Elem => Zipper[Elem]) = t andThen (_.unselect.head match {
  case e: Elem => e
  case _ => throw new RuntimeException("Aaaaah! This was never meant to happen!")
})

然后你可以这样写:

val transforms: Seq[Elem => Zipper[Elem]] = Seq(
  _ \\ "book" filter (_.attrs("year").toInt > 2000),
  _ \\ "book" filter (_.attrs("title").contains("J"))
)

val result = Function.chain(transforms map toEndo)(lib)

请注意,我已将 unselect 移到助手中,以提高类型安全性。

关于xml - AntiXML 中的链接转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12026068/

相关文章:

c# - 如何使用 C# 和 XML 获取根元素的直接子元素?

scala - Scala Vector 中的结构共享

scala - 将查询字符串转换为 Scala 中的映射

scala - 运行 Play 应用程序的 SBT 在开始使用 scala.sys.process.run 时立即退出?

java - JAXB 更改默认命名转换器

iphone - 如何将 XML 作为字符串发送到 Soap Action?

XML DOM SelectSingleNode() 命名空间不返回节点

xml - 如何与电子商务平台 Hybris 交互

scala - 如何将元组声明为函数的返回类型以及如何在 Scala 的调用方代码中访问元组?

java - Scala 重载不选择最具体的方法