[Java]文字参照から文字への変換

えー、久々にお仕事ネタです。(たまには書かないと・・・)

Javaで、XMLのエスケープ処理とかの実装を調査する機会がありまして、ちょっとハマったので、覚書としてメモしておきます。

XML文書をパースする際には、定義済み実体参照を置換すること(例えば、<を<にするとか)は理解していたんですが、文字参照(&#で始まる10進や、&#xで始まる16進)を文字に置換するというのを忘れておりまして。


そこで、16進数字から文字へ変換する処理を実装しようと、APIを探したんですが、コレ!というのが見当たりません。ググってもなかなかヒットしない。逆(文字から16進数字)は、Integer#toHexStringでできるんですが・・・。

じゃ自作するか、と同僚とアレコレやってみました。intにしてbyte配列にしてビット演算して・・・と試行錯誤して何とか出来たは出来たんですが、イマイチすっきりしなくて。

ダメ元で、もう一度キーワードを変えてググったら・・・やっとよさげなのにヒットしました。

■[Java][覚書]NcrCodec

decodeメソッドだけ抜粋。

// NCRデコードを行う(10進、16進)

public static String decode(String str) {
    Pattern pattern = Pattern.compile("&#(\\d+);|&#([\\da-fA-F]+);");
    Matcher matcher = pattern.matcher(str);
    StringBuffer sb = new StringBuffer();
    Character buf;
    while(matcher.find()){
        if(matcher.group(1) != null){
            buf = new Character(
                      (char)Integer.parseInt(matcher.group(1)));
        }else{
            buf = new Character(
                      (char)Integer.parseInt(matcher.group(2), 16));
        }
        matcher.appendReplacement(sb, buf.toString());
    }
    matcher.appendTail(sb);
    return sb.toString();
}

なるほど。Integer#parseIntした値をcharでキャストしてCharacterに食わせればいいのか・・・うーん、こんなに簡単だったとは・・・。

しかも、「&#x○○○○;」を抽出する正規表現のロジックも載ってるし。Matcherってこうやって使うのね。appendReplacementか・・・勉強になります。

以上、覚書でした。

なんか、今どきXMLパース処理なんて、”車輪の再発明”しているような気がしないでもないですが、XML1.0勧告をちゃんと読むいい機会になりました。

One thought on “[Java]文字参照から文字への変換

コメントを残す

メールアドレスが公開されることはありません。