Java DOMパーサーを使用してXMLファイルを解析すると、次の結果になります。
[Fatal Error] os__flag_8c.xml:103:135: An invalid XML character (Unicode: 0xc) was found in the element content of the document.
org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0xc) was found in the element content of the document.
at com.Sun.org.Apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.Sun.org.Apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
データをCDATAブロックにカプセル化する場合でも、XMLドキュメントでは許可されない文字がいくつかあります。
ドキュメントを生成した場合、次のことが必要です。 エンティティエンコードまたは それを取り除きます。誤ったドキュメントがある場合は、解析する前にこれらの文字を削除する必要があります。
このスレッドのドルメンの回答を参照してください: XMLの無効な文字
この記事へのリンク先: http://www.w3.org/TR/xml/#charsets
基本的に、0x9(TAB)、0xA(CR?)、0xD(LF?)を除く、0x20未満のすべての文字は許可されません
public String stripNonValidXMLCharacters(String in) {
StringBuffer out = new StringBuffer(); // Used to hold the output.
char current; // Used to reference the current character.
if (in == null || ("".equals(in))) return ""; // vacancy test.
for (int i = 0; i < in.length(); i++) {
current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen.
if ((current == 0x9) ||
(current == 0xA) ||
(current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)) ||
((current >= 0x10000) && (current <= 0x10FFFF)))
out.append(current);
}
return out.toString();
}
文字0x0CはXML 1.0では無効ですが、 XML 1.1では有効な文字 になります。したがって、xmlファイルでプロローグでバージョン1.1が指定されていない限り、それは単に無効であり、このファイルのプロデューサーに文句を言う必要があります。
このリンクには、Javaというコードがあり、完全に正常に動作します。
http://blog.mark-mclaren.info/2007/02/invalid-xml-characters-when-valid-utf8_5873.html
無効なxml文字がxmlになるたびに、このようなエラーが発生します。 uをnotepad ++で開くと、VT、SOH、FFのように見えますが、これらは無効なxml文字です。私はXMLバージョン1.0を使用しており、パターンごとにデータベースに入力する前にテキストデータを検証します
Pattern p = Pattern.compile("[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFF]+");
retunContent = p.matcher(retunContent).replaceAll("");
無効な特殊文字がxmlに入力されないようにします
カスタムのFilterReaderクラスを使用して、すべての「無効な」文字をフィルタリングできます。
public class InvalidXmlCharacterFilter extends FilterReader {
protected InvalidXmlCharacterFilter(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 read;
for (int i = off; i < off + read; i++) {
if (!XMLChar.isValid(cbuf[i])) cbuf[i] = '?';
}
return read;
}
}
そして、次のように実行します:
InputStream fileStream = new FileInputStream(xmlFile);
Reader reader = new BufferedReader(new InputStreamReader(fileStream, charset));
InvalidXmlCharacterFilter filter = new InvalidXmlCharacterFilter(reader);
InputSource is = new InputSource(filter);
xmlReader.parse(is);
これらの答えはすべて、ユーザーがgSOAPから受け取るのではなく、悪いXMLを生成していることを前提としているようです。
バイト配列を文字列に読み込んで、JAXBを使用してオブジェクトに変換しようとしている場合は、次のようにバイト配列から文字列を作成して「iso-8859-1」エンコーディングを追加できます。
文字列JAXBallowedString = new String(byte [] input、 "iso-8859-1");
これにより、競合するバイトが、JAXBが処理できるシングルバイトエンコーディングに置き換えられます。明らかに、この解決策はxmlを解析することだけです。
XMLに制御文字が含まれていた同様の問題に直面しました。コードを調べた結果、文字列コンテンツの読み取りに非推奨のクラスであるStringBufferInputStreamが使用されていることがわかりました。
http://docs.Oracle.com/javase/7/docs/api/Java/io/StringBufferInputStream.html
This class does not properly convert characters into bytes. As of JDK 1.1, the preferred way to create a stream from a string is via the StringReader class.
ByteArrayInputStreamに変更したところ、うまく機能しました。