7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaでXML有効文字以外をコード値指定で弾く

Last updated at Posted at 2017-08-01

はじめに

仕事でXMLを取り込む事があったんだけどその時に相手が制御コードを仕込んできた。

取り込みには下記のメソッドを使用していた。

Unmarshaller#unmarshal(XMLStreamReader reader, Class declaredType)

XMLの中身を文字列として取得⇒ストリームに変換⇒オブジェクト化という流れだ。

そして下記のエラーが出る。

Message: ドキュメントの要素コンテンツに無効なXML文字(Unicode: 0x2)が見つかりました。
※無効な文字は何個かあったけど省略

で、相手側が直してくれないらしいので文字列置換で無効なXML文字を取り除くことになった。

XMLで使える文字列

W3C勧告文書

上記サイトによるとXMLで使える文字のコード値は下記の6パターンとのこと

① #x9 ⇒ タブ
② #xA ⇒ 改行(LF)
③ #xD ⇒ 改行(CR)
④ [#x20-#xD7FF] ⇒ 半角スペース~ハングル
⑤ [#xE000-#xFFFD] ⇒ 外字~特殊用途文字
⑥ [#x10000-#x10FFFF] ⇒ 線文字B音節文字~未定義

まぁ基本的に使う文字は④に入ってると思って貰えばいい

一応、Unicodeにおける文字とコード値の表を置いておく

Unicode一覧表

Javaでの表現

javaでコード値指定して置換する場合、こういう風に書く。
下記は半角スペースをブランクに置換している。
Matcherとか使ってもいいんだけどとりあえずString#replaceAllでも正規表現は使える。

String str = "XMLを文字列化したもの";
str = str.replaceAll("\\u0020", "");

Javaだと「\x00」で2桁の文字コードで「\u0000」で4桁の文字コードが書ける。
バックラッシュが2つ書いてあるのはエスケープです。

全部4桁で書くとこうなる
① #x9 ⇒ "\u0009"
② #xA ⇒ "\u000A"
③ #xD ⇒ "\u000D"
④ [#x20-#xD7FF] ⇒ "[\u0020-\uD7FF]"
⑤ [#xE000-#xFFFD] ⇒ "[\uE000-\uFFFD]"

待て・・・Unicodeだと5桁以上もあるじゃないか・・・どうやって表現すればいいんだと思ったが
正規表現で複数桁のコード値を指定する方法があった。

⑥ [#x10000-#x10FFFF] ⇒ "[\x{10000}-\x{10FFFF}]"

これでいいらしい。

合体させて拒否る

正規表現はOR判定できるのでパイプでくっつけて、全部否定する。

String str = "XMLを文字列化したもの";
str = str.replaceAll("(?!\\u0009|\\u000A|\\u000D|[\\u0020-\\uD7FF]|[\\uE000-\\uFFFD]|[\\x{10000}-\\x{10FFFF}]).", "");

これで使えない文字を外したうえで取り込みができた。
正規表現の部分で最後に「.」(ドット)を書かないと反応しなくてずっと悩んだけど
とりあえずこれで使えない文字を外すことはできた。

2017/08/02追加
コメントで指摘されたんだけどこれでもできる。
言われて気づいたが、なんでかパイプで区切っておかないといけないと勘違いしていた。

String str = "XMLを文字列化したもの";
str = str.replaceAll("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\x{10000}-\\x{10FFFF}]", "");

最後に

WEBで調べた時に「含まない文字を除去」っていうのが見つからなかったので今回の記事を書きました。
含まない行を検索する方法はいっぱい出てくるんだけどね。

7
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?