2013-03-14 8 views
5

Chciałbym funkcji Scala, aby zwrócić String &, gdy podane dane wejściowe &, podobnie dla wszystkich innych znaków XML Escaped.Jak przywrócić znaki ze znaków ewakuacyjnych XML (XML unescape)?

próbowałem użyć xml.Unparsed, może w niewłaściwy sposób, że nie daje mój pożądany wynik:

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; 

Mam również próbował użyć xml.Utility.unescape, ale to nie daje żadnego wyjścia w ogóle :

scala> val sb = new StringBuilder 
sb: StringBuilder = 

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

scala> sb.toString 
res1: String = "" 

scala> 

Odpowiedz

6

Jeśli chcesz po prostu dostać kodów zmiany znaczenia ciągi z obiektów XML, text jest twoim przyjacielem:

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

Implementacja tego jest w scala.xml.EntityRef. Uzyskanie funkcji, która wykonuje dokładnie to, o co prosisz, nie jest zbyt proste, ponieważ biblioteka nie wykonuje analizowania tekstu (odbywa się to za pomocą analizatora składni Java SAX) i dlatego najpierw musisz zmienić swój "&amp;" w EntityRef, abyś mógł nazwij to, co wydaje się ogromną ilością odpadów, biorąc pod uwagę, jak prosta jest implementacja text.

0

nie znalazłem nic w scala.xml.Utility ... Zrobiłem to szybki i brudny z tym:

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

Brudny rzeczywiście. 'scala> unescape (" foo & bar ") res3: String = foo \ bar' – erich2k8

Powiązane problemy