2013-03-14 15 views
5

Vorrei una funzione Scala per restituire String & quando viene fornito l'input &, in modo simile per tutti gli altri caratteri di escape XML.Come ripristinare i caratteri di escape XML (XML unescape)?

Ho cercato di usare xml.Unparsed, forse in modo sbagliato, non dare il mio l'output desiderato:

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; 

Ho anche tentato di usare xml.Utility.unescape, ma non dà alcun output a tutti :

scala> val sb = new StringBuilder 
sb: StringBuilder = 

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

scala> sb.toString 
res1: String = "" 

scala> 

risposta

6

Se si desidera ottenere le stringhe escape di oggetti XML, text è tuo amico:

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 = & 

L'implementazione di questo è in scala.xml.EntityRef. Ottenere una funzione che fa esattamente quello che stai chiedendo non è molto semplice dato che la libreria non esegue l'analisi del testo (è fatta dal parser Java SAX) e quindi devi prima trasformare il tuo "&amp;" in un EntityRef in modo che tu possa chiamalo, il che sembra una grande quantità di sprechi, data la semplice implementazione di text.

0

non ho trovato nulla in scala.xml.Utility ... ho fatto rapido e sporco con questo:

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) 
} 
+0

sporco davvero. 'scala> unescape (" foo & bar ") res3: String = foo \ bar' – erich2k8

Problemi correlati