如何将Scala Elem转换为NodeSeq

时间:2016-08-03 14:08:08

标签: xml scala

我正在尝试编写一个XML RewriteRule,它将子元素包装在一个包装元素中,以便规范化一堆不同的xml文件。这就是我需要它,但我最终得到了一个Elem,为了覆盖transform()函数,我需要返回一个NodeSeq。

  /* WRAP NODES INSIDE PARENT NODE
   *
   * Some Nodes should be wrapped in an enclosing Node.  For example, some xml versions
   * of the article <contentitem> have <category> as a direct child, but category info  
   * should really have this structure:
   *   <categories>
   *     <category>some category name</category>
   *   </categories>
   */
  val wrapIndividualNodes = new RewriteRule {
    val nodesToWrap = List( ("category", "categories"), ("subcategory", "subcategories") )

    override def transform(n: Node): NodeSeq = {
      for ( (target, wrapper) <- nodesToWrap ) {

        // copy, then delete, children
        val categoryNodes = (n \ target)
        val articleWithoutCategoryNodes = SharedRules.deleteChildren(n, target)

        // wrap children and add as new child
        val categories = <categories>{categoryNodes}</categories>
        SharedRules.addChild(articleWithoutCategoryNodes, categories)

      }
    }
  }

SharedRules.scala

  /**
    * Adds newChild as the last element in the parent node
    */
  def addChild(parent: Node, child: Node): Elem = {
    parent.copy(child = parent.child ++ child)
  }

  /**
    * Deletes all children with matching childLabel from parent
    */
  def deleteChildren(parent: Node, childLabel: String): Elem = {
    parent.copy( child = parent.child.filterNot(_.label == childLabel))
  }

1 个答案:

答案 0 :(得分:6)

根据您要实现的目标,有两种方法可以从NodeSeq获取val elem: Elem

  • 不做任何事情val ns: NodeSeq = elem将起作用,因为Elem扩展了Node和Node扩展NodeSeq。
  • 制作一个单独的Seq val ns: NodeSeq = elem.theSeq,它实际上将你的Elem包裹在Seq [Node]中,而Seq [Node]将被隐式转换为NodeSeq。