方法返回NodeBuffer而不是Elem,这违反了类型检查规则

时间:2013-12-27 05:47:20

标签: xml scala

有两种方法,都返回xml:

 def method1 = 
   <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope>
      <soap:Header>
        {Elem(....)}
      </soap:Header>
    </soap:Envelope>

 def method2 = 
  <someXml>
    //.......
  </someXml>

还有一种获得Elem的方法:

def method3(a: Elem) = //....

val xml1 = method1
val xml2 = method2

method3(xml1) //error
method3(xml2) //ok

它说method1会返回NodeBuffer而它无法接受,而method2会返回Elem,这很完美。

为什么?我该怎么办呢?

2 个答案:

答案 0 :(得分:5)

scala> def method1 = <?xml version="1.0" encoding="utf-8"?><root />
method1: scala.xml.NodeBuffer

method1中,您尝试创建的xml不是XML declaration,而是2 Node s:Processing instruction(scala类型{{3} })和Elem

scala> <?abc attr1="v1" attr2="v2" ?>
res0: scala.xml.ProcInstr = <?abc attr1="v1" attr2="v2" ?>

2个节点的序列为您提供了一组节点 - NodeBuffer

scala> <a/><b/>
res0: scala.xml.NodeBuffer = ArrayBuffer(<a/>, <b/>)

实际上你不能手动使用处理指令xml

scala> <?xml version="1.0" encoding="utf-8"?>
java.lang.IllegalArgumentException: xml is reserved

删除它。

如果您需要序列化版本的XML声明,则应使用XML.writeXML.save xmlDecl = true

import xml.XML
val myXml = <root />
val writer = new java.io.StringWriter
XML.write(writer, myXml, "utf-8", xmlDecl = true, doctype = null)
writer.toString
// <?xml version='1.0' encoding='utf-8'?>
// <root/>

答案 1 :(得分:0)

另一种方法是将最终组装的XML转换为XHTML字符串。

我用Play框架完成了这个,我使用Scala内置的XML支持代替所谓的Twirl模板(好吧,我仍然使用他们的Html包装器,但其他一切都是纯粹的XML)。以下内容允许您保留OP案例和许多其他行所需的<?xml version="1.0" encoding="UTF-8"?>行,例如:生成XML站点地图。

import scala.xml.Xhtml

Html{
s"""
<?xml version="1.0" encoding="UTF-8"?>
${Xhtml.toXhtml(
  <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  ...
)}
"""
}

在发送给客户之前,请将其作为最后一步。 toXhtml当然可以通过XML传递(即不必像上面那样手动定义)