エンコーディング「UTF-8」を使用してオブジェクトをXMLファイルにマーシャリングしています。ファイルを正常に生成します。しかし、それを元に戻そうとすると、エラーが発生します。
属性「{1}」の値に無効なXML文字(Unicode:0x {2})が見つかり、要素は「0」です。
文字は0x1Aまたは\u001aです。これは、UTF-8では有効ですが、XMLでは無効です。JAXBのMarshallerは、この文字をXMLファイルに書き込むことを許可しますが、Unmarshallerはそれを解析して戻すことはできません。別のエンコーディング(UTF-16、ASCIIなど)を使用しようとしましたが、それでもエラーが発生します。
一般的な解決策は、XML解析の前に、この無効な文字を削除/置換することです。しかし、このキャラクターを元に戻す必要がある場合、マーシャリングを解除した後に元のキャラクターを取得するにはどうすればよいですか?
この解決策を探している間、マーシャリングを解除する前に、無効な文字を置換文字(たとえば、dot = "。")に置き換えたいと思います。
私はこのクラスを作成しました:
public class InvalidXMLCharacterFilterReader extends FilterReader {
public static final char substitute = '.';
public InvalidXMLCharacterFilterReader(Reader in) {
super(in);
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int read = super.read(cbuf, off, len);
if (read == -1)
return -1;
for (int readPos = off; readPos < off + read; readPos++) {
if(!isValid(cbuf[readPos])) {
cbuf[readPos] = substitute;
}
}
return readPos - off + 1;
}
public boolean isValid(char c) {
if((c == 0x9)
|| (c == 0xA)
|| (c == 0xD)
|| ((c >= 0x20) && (c <= 0xD7FF))
|| ((c >= 0xE000) && (c <= 0xFFFD))
|| ((c >= 0x10000) && (c <= 0x10FFFF)))
{
return true;
} else
return false;
}
}
次に、これが私がファイルを読み取ってマーシャリング解除する方法です。
FileReader fileReader = new FileReader(this.getFile());
Reader reader = new InvalidXMLCharacterFilterReader(fileReader);
Object o = (Object)um.unmarshal(reader);
どういうわけか、リーダーは無効な文字を私が望む文字に置き換えません。誤ったXMLデータが生成され、マーシャリングを解除できません。InvalidXMLCharacterFilterReaderクラスに何か問題がありますか?