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



有 2 个方法,都返回 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这完全没问题。

为什么?我该怎么办?

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

method1中,您尝试创建的不是带有XML declarationxml,而是 2 Node s:处理指令(scala 类型 ProcInstr)和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.savexmlDecl = 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/>

另一种方法是将最终组装的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中传递(即不必像我上面所做的那样手动定义)

最新更新