5

我希望 Scala 函数&在给定 input 时返回 String &,对于所有其他 XML 转义字符也是如此。

我尝试使用xml.Unparsed,可能以错误的方式使用,它没有给出我想要的输出:

scala> val amp = '&'
amp: Char = &

scala> <a>{amp}</a>.toString
res0: String = <a>&amp;</a>

scala> import scala.xml._
import scala.xml._

scala> <a>{amp}</a>.child(0)
res1: scala.xml.Node = &amp;

scala> xml.Unparsed(<a>{amp}</a>.child(0).toString)
res2: scala.xml.Unparsed = &amp;

我也尝试过使用xml.Utility.unescape,但它根本没有给出任何输出:

scala> val sb = new StringBuilder
sb: StringBuilder = 

scala> xml.Utility.unescape("&amp;", sb)
res0: StringBuilder = null

scala> sb.toString
res1: String = ""

scala> 
4

2 回答 2

6

如果您只想从 XML 对象中获取text未转义的字符串,您的朋友是:

scala> val el = <a>{amp}</a>
el: scala.xml.Elem = <a>&amp;</a>
scala> el.child(0)
res4: scala.xml.Node = &amp;
scala> el.child(0).text
res5: String = &

这个的实现在scala.xml.EntityRef. 获得一个完全符合您要求的函数并不是非常简单,因为该库不进行文本解析(它由 Java SAX 解析器完成),因此您首先需要将您的"&amp;"变成一个EntityRef以便您可以调用它,考虑到实现的简单程度,这似乎是一种巨大的浪费text

于 2013-03-14T11:10:35.393 回答
0

我在 scala.xml.Utility 中没有找到任何东西......我用这个快速而肮脏地做到了:

def unescape(text: String): String = {
  def recUnescape(textList: List[Char], acc: String, escapeFlag: Boolean): String = {
    textList match {
      case Nil => acc
      case '&' :: tail => recUnescape(tail, acc, true)
      case ';' :: tail if (escapeFlag) => recUnescape(tail, acc, false)
      case 'a' :: 'm' :: 'p' :: tail if (escapeFlag) => recUnescape(tail, acc + "&", true)
      case 'q' :: 'u' :: 'o' :: 't' :: tail if (escapeFlag) => recUnescape(tail, acc + "\"", true)
      case 'l' :: 't' :: tail if (escapeFlag) => recUnescape(tail, acc + "<", true)
      case 'g' :: 't' :: tail if (escapeFlag) => recUnescape(tail, acc + ">", true)
      case x :: tail => recUnescape(tail, acc + x, true)
      case _ => acc
    }
  }
  recUnescape(text.toList, "", false)
}
于 2014-01-20T10:19:16.933 回答