ということで、大体こんな感じ(文字実体参照)
文字実体参照は、いちいち手入力してたら、日が暮れそうだったので、スクリプトでコードの断片を作成することにした。Webサイトから、文字実体参照の個所を抜き出す。次のような内容が並ぶ感じ。
<!ENTITY nbsp CDATA " " -- no-break space = non-breaking space, U+00A0 ISOnum --> <!ENTITY iexcl CDATA "¡" -- inverted exclamation mark, U+00A1 ISOnum --> ...(省略) ...
(行の前半は)規則正しく並んでいるので、awk で切り出しちゃえばいい。
grep ENTITY entities.txt | awk '{print "m_entitiesMap.put( \"" $2 "\", " $4 ");"}' \ | sed -e 's|"&#|new Character\(\(char\)|' | sed -e 's|;"|\)|' m_entitiesMap.put( "nbsp", new Character((char)160)); m_entitiesMap.put( "iexcl", new Character((char)161)); ...(省略)...
あとは、適当にクラスの初期化部分などで利用すればいい。( は、32 に置き換えるように変更...。) あとは、正規表現で切り出された文字列によって、変更すればいい。
private static final Map m_entitiesMap = new HashMap(); static { m_entitiesMap.put( "nbsp", new Character((char)32)); // replace from 160 to 32 m_entitiesMap.put( "iexcl", new Character((char)161)); ...(省略)... } private String unescapeHtmlText(String src) { StringBuffer buff = new StringBuffer(); Matcher matcher = UNESCAPE_HTML_PATTERN.matcher(src); int prevPos = 0; while (matcher.find(prevPos)) { buff.append(src.substring(prevPos, matcher.start())); String matchedText = matcher.group(1); int charNum; Object charObj = m_entitiesMap.get(matchedText); if (charObj != null) { // some entity. buff.append(((Character)charObj).charValue()); } else if ('#' == matchedText.charAt(0)) { int radix = 10; int charStartIndex = 1; if (matchedText.length() > 1 && ('x' == matchedText.charAt(1) || 'X' == matchedText.charAt(1))) { radix = 16; charStartIndex = 2; } try { charNum = Integer.parseInt( matchedText.substring(charStartIndex), radix); buff.append((char)charNum); } catch (NumberFormatException e) { buff.append(matcher.group()); } } else { buff.append(matcher.group()); } prevPos = matcher.end(); } if (prevPos < src.length()) buff.append(src.substring(prevPos)); return new String(buff); }
他にもやり方有ると思うけど、とりあえず、前の場合のテストはパス。
まぁ、多分、問題ないでしょう。。。