在Scala中使用动态标签和属性构造XML?

Joe*_*Joe 25 xml scala

我希望能够这样做:

val myXml = <myTag { someAttributes }> </myTag>
Run Code Online (Sandbox Code Playgroud)

(因为我不知道编译时属性细节是什么)

还有这个:

val myXml = <{someTag}></{someTag}>
Run Code Online (Sandbox Code Playgroud)

这不是有效的Scala语法.我最接近的是使用Elem对象来构造元素,但它有点麻烦(插入我不想要的PCDATA).有没有像上面这样做的方法?

Dan*_*ral 25

val myXml = <myTag/> % Attribute(None, "name", Text("value"), Null)
Run Code Online (Sandbox Code Playgroud)

请参阅scala.xml.Attribute不同的构造函数.

为所有子项添加相同的属性:

scala> val xml = <root><a/><b/><c/></root>
xml: scala.xml.Elem = <root><a></a><b></b><c></c></root>

scala> xml.child map (_ match {
     | case elem : Elem => elem % Attribute(None, "name", Text("value"), Null)
     | case x => x
     | })
res3: Sequence[scala.xml.Node] = ArrayBuffer(<a name="value"></a>, <b name="value"></b>, <c name="value"></c>)
Run Code Online (Sandbox Code Playgroud)

您还可以使用scala.xml.transform中的内容以递归方式对所有XML执行此操作:

val rr = new RewriteRule {
  override def transform(n: Node): Seq[Node] = n match {
    case elem : Elem => elem % Attribute(None, "name", Text("value"), Null) toSeq
    case other => other
  }
}

val rt = new RuleTransformer(rr)

scala> rt(xml)
res5: scala.xml.Node = <root name="value"><a name="value"></a><b name="value"></b><c name="value"></c></root>
Run Code Online (Sandbox Code Playgroud)

或者您可以将属性添加到xml的任意部分:

scala> val xml = <root>{<a/> % Attribute(None, "name", Text("value"), Null)}</root>
xml: scala.xml.Elem = <root><a name="value"></a></root>
Run Code Online (Sandbox Code Playgroud)

编辑

在Scala 2.8上更改名称很容易,如下所示:

val someTag = "tag"
val myXml = <root>{<a/>.copy(label = someTag)}</root>
Run Code Online (Sandbox Code Playgroud)


Hen*_*ory 10

注意:你需要

import scala.xml.Null
Run Code Online (Sandbox Code Playgroud)

让它工作,而不是scala.Null,这也存在.