【问题标题】:Construct XML with dynamic label and attributes in Scala?在 Scala 中构造带有动态标签和属性的 XML?
【发布时间】:2010-12-08 17:31:33
【问题描述】:

我希望能够做到这一点:

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

(因为编译时不知道属性详细信息是什么)

还有这个:

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

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

【问题讨论】:

    标签: xml scala


    【解决方案1】:

    注意:你需要

    import scala.xml.Null
    

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

    【讨论】:

    • 谢谢!看了丹尼尔的回复,我以为“Null”是错​​字,改写了“null”。
    【解决方案2】:
    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>
    

    【讨论】:

    • 这不允许我创建一个带有给定标签的节点。我看不到创建任意 XML 结构的方法。 Elem 的提取器有一个用于儿童的可变参数。我希望能够传递一个 NodeSeq(任何大小)。
    • 在 OP 中的第二个 sn-ps 中创建节点的任何方式?
    • @IttayD 不知怎的我错过了!
    • 顺便说一句,您可以使用 :_* 运算符将 NodeSeq 作为 varargs 传入,该运算符指示编译器将集合一一传递。所以:Elem(blah,blah,blah,(mySeq:_*))
    • Attribute() 的缺点是它不会保留您正在编写的属性链的顺序。这对计算机来说不是问题,但如果你不能保证元素的第一个属性是“名称”属性,那么对于真人来说就不是很清楚了
    猜你喜欢
    • 2017-05-27
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2011-06-07
    相关资源
    最近更新 更多