2009-10-21 44 views
23

我希望能够做到这一点:在Scala中构建具有动态标签和属性的XML?

val myXml = <myTag { someAttributes }> </myTag> 

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

这:

val myXml = <{someTag}></{someTag}> 

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

回答

24
val myXml = <myTag/> % Attribute(None, "name", Text("value"), Null) 

对于不同的构造函数,请参阅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>) 

您还可以使用在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> 

也可以添加属性到xml的任意部分:

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

编辑

更改名称是很容易做的Scala 2.8,这样的:

val someTag = "tag" 
val myXml = <root>{<a/>.copy(label = someTag)}</root> 
+0

非常感谢! – Joe 2009-10-21 15:39:10

+1

虽然这不让我创建具有给定标签的节点。我看不到创建任意XML结构的方法。 Elem提取器为儿童提供可变参数。我希望能够通过一个NodeSeq(任何大小)。 – Joe 2009-10-21 16:41:48

+0

任何方式创建一个节点,如在OP中的第二个片段? – IttayD 2010-05-26 12:58:43

8

注意:您需要

import scala.xml.Null 

得到这个工作,而不是scala.Null,这也存在。

+0

谢谢!在阅读Daniel的回复之后,我认为“Null”是一个错字,而是写了“null”。 – KajMagnus 2011-02-07 05:41:08

相关问题