HTML entity - 文字コード

こんにちは。
Webサービスを開発していろいろ HTML entity に関してTipsがあったので、備忘録を兼ねてブログを書きます。
なお以下で半角の「&」を全角の「&」で記述しています。
それでは、早速書いてみます。

  • ホワイトスペース文字の問題。

ホワイトスペース文字とはWIKIにあります。
http://ja.wikipedia.org/wiki/Unicode%E6%96%87%E5%AD%97%E3%81%AE%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0#.E3.83.9B.E3.83.AF.E3.82.A4.E3.83.88.E3.82.B9.E3.83.9A.E3.83.BC.E3.82.B9.E6.96.87.E5.AD.97
ここで問題になったのが、 U+2028 = 
 と U+2029 = 
 です。
他にも問題になる文字があるかもしれませんが、ホワイトスペースでは上記です。

これが出力方法にもよりますが、JavaScriptに影響を与えました。
結論は、ちゃんとEscapeすればいいのです。
特に、 
 と 
 です。

  • ホワイトスペース文字の種類詳細。

ちなみに、なにがあるのか記載しておきます。

	 =U+0009
http://www.fileformat.info/info/unicode/char/0009/index.htm

 =U+000A
http://www.fileformat.info/info/unicode/char/000A/index.htm
 =U+000B
http://www.fileformat.info/info/unicode/char/000B/index.htm
 =U+000C
http://www.fileformat.info/info/unicode/char/000C/index.htm

 =U+000D
http://www.fileformat.info/info/unicode/char/000D/index.htm
… =U+0085
http://www.fileformat.info/info/unicode/char/0085/index.htm
  =U+0020
http://www.fileformat.info/info/unicode/char/0020/index.htm

 =U+2028
http://www.fileformat.info/info/unicode/char/2028/index.htm

 =U+2029
http://www.fileformat.info/info/unicode/char/2029/index.htm

  • HTML entity のエスケープ方法。

Javaの場合、ライブラリで、apache-commons-langを使えばエスケープできます。

    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
    StringEscapeUtils.escapeHtml(new String(\u2038));
    • commons-langコード(※参考のために抜粋)

http://commons.apache.org/lang/api-2.6/index.html

    /**
     * <p>
     * Escapes the characters in the <code>String</code> passed and writes the result to the <code>Writer</code>
     * passed.
     * </p>
     * 
     * @param writer
     *            The <code>Writer</code> to write the results of the escaping to. Assumed to be a non-null value.
     * @param str
     *            The <code>String</code> to escape. Assumed to be a non-null value.
     * @throws IOException
     *             when <code>Writer</code> passed throws the exception from calls to the {@link Writer#write(int)}
     *             methods.
     * 
     * @see #escape(String)
     * @see Writer
     */
    public void escape(Writer writer, String str) throws IOException {
        int len = str.length();
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            String entityName = this.entityName(c);
            if (entityName == null) {
                if (c > 0x7F) {
                    writer.write("&#");
                    writer.write(Integer.toString(c, 10));
                    writer.write(';');
                } else {
                    writer.write(c);
                }
            } else {
                writer.write('&');
                writer.write(entityName);
                writer.write(';');
            }
        }
    }
  • 余談ですが、StringEscapeUtilsはいろいろあります。
    escapeJava(String) : String
    escapeJava(Writer, String) : void
    unescapeJava(String) : String
    unescapeJava(Writer, String) : void
    escapeJavaScript(String) : String
    escapeJavaScript(Writer, String) : void
    unescapeJavaScript(String) : String
    unescapeJavaScript(Writer, String) : void
    escapeHtml(String) : String
    escapeHtml(Writer, String) : void
    unescapeHtml(String) : String
    unescapeHtml(Writer, String) : void
    escapeXml(String) : String
    escapeXml(Writer, String) : void
    unescapeXml(String) : String
    unescapeXml(Writer, String) : void
    escapeCsv(String) : String
    escapeCsv(Writer, String) : void
    unescapeCsv(String) : String
    unescapeCsv(Writer, String) : void
    escapeSql(String) : String
  • 最後に。

どんなときも文字コード対策は悩みの種ですね。
マルチバイドの国に生まれたために、表現豊かな文章は魅力ですが、プログラミングでは不毛な悩みが多いですね。
もっと便利なプログラミング言語を開発しろってことなのかもしれませんが。。。