XMLエラーの原因となる制御コード0x6

私はXMLでデータをフェッチするJavaアプリケーションを実行していますが、しばらくの間、何らかのデータが何らかの制御コードで構成されていますか?

An invalid xml character (Unicode: 0x6) was found in the CDATA section.
org.xml.sax.SAXParseException: An invalid xml character (Unicode: 0x6) was found in     the CDATA section.
    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 domain.Main.processLogFromUrl(Main.java:342)
    at domain.Main.(Main.java:67)
    at domain.Main.main(Main.java:577)

私は多くの情報を見つけることができないので、誰もこのコントロールコードが正確に何を説明することができますか?

前もって感謝します。

2
あなたがUnicode文字を期待しておらず、UTF-8が普通に得られたものなら、誰がUnicode文字を応答に入れていますか?
追加された 著者 djangofan,
@ djangofan、よくデータを担当していたWebサービスがシステムをチェックしていますが、それはほぼ1ヶ月に1回発生します。
追加された 著者 JavaCake,
Wikipedia: en.wikipedia.org/wiki/Acknowledge_character を参照してください。
追加された 著者 rekire,
Javaが間違っているわけではありません、あなたのXMLソースが壊れていて、それを修正するために誰かが作成責任を負う必要があります。バックグラウンドについての同様の質問:xml1を使用しているユニコード文字0x2の1つの ">" stackoverflowを、 追加された 著者 bobince,

3 答え

XMLをバージョン1.1として定義してみてください:

<?xml version="1.1"?>
2
追加された
役に立たない。制御文字はXML 1.1でも制限されています。
追加された 著者 jasso,

フィルタリングするには、 FilterInputStream を記述する必要があります。 SAXパーサが取得する前のデータ不良データを削除または再コードする必要があります。

Apacheには超柔軟なの例があります。はるかに単純なものをまとめることをお勧めします。

ここで私は他の掃除をする鉱山の一つですが、それは良いスタートになると確信しています。

/* Cleans up often very bad xml. 
 * 
 * 1. Strips leading white space.
 * 2. Recodes £ etc to &#...;.
 * 3. Recodes lone & as &.
 * 
 */
public class XMLInputStream extends FilterInputStream {

  private static final int MIN_LENGTH = 2;
 //Everything we've read.
  StringBuilder red = new StringBuilder();
 //Data I have pushed back.
  StringBuilder pushBack = new StringBuilder();
 //How much we've given them.
  int given = 0;
 //How much we've read.
  int pulled = 0;

  public XMLInputStream(InputStream in) {
    super(in);
  }

  public int length() {
   //NB: This is a Troll length (i.e. it goes 1, 2, many) so 2 actually means "at least 2"

    try {
      StringBuilder s = read(MIN_LENGTH);
      pushBack.append(s);
      return s.length();
    } catch (IOException ex) {
      log.warning("Oops ", ex);
    }
    return 0;
  }

  private StringBuilder read(int n) throws IOException {
   //Input stream finished?
    boolean eof = false;
   //Read that many.
    StringBuilder s = new StringBuilder(n);
    while (s.length() < n && !eof) {
     //Always get from the pushBack buffer.
      if (pushBack.length() == 0) {
       //Read something from the stream into pushBack.
        eof = readIntoPushBack();
      }

     //Pushback only contains deliverable codes.
      if (pushBack.length() > 0) {
       //Grab one character
        s.append(pushBack.charAt(0));
       //Remove it from pushBack
        pushBack.deleteCharAt(0);
      }

    }
    return s;
  }

 //Returns false at eof.
 //Might not actually push back anything but usually will.
  private boolean readIntoPushBack() throws IOException {
   //File finished?
    boolean eof = false;
   //Next char.
    int ch = in.read();
    if (ch >= 0) {
     //Discard whitespace at start?
      if (!(pulled == 0 && isWhiteSpace(ch))) {
       //Good code.
        pulled += 1;
       //Parse out the &stuff;
        if (ch == '&') {
         //Process the &
          readAmpersand();
        } else {
         //Not an '&', just append.
          pushBack.append((char) ch);
        }
      }
    } else {
     //Hit end of file.
      eof = true;
    }
    return eof;
  }

 //Deal with an ampersand in the stream.
  private void readAmpersand() throws IOException {
   //Read the whole word, up to and including the ;
    StringBuilder reference = new StringBuilder();
    int ch;
   //Should end in a ';'
    for (ch = in.read(); isAlphaNumeric(ch); ch = in.read()) {
      reference.append((char) ch);
    }
   //Did we tidily finish?
    if (ch == ';') {
     //Yes! Translate it into a &#nnn; code.
      String code = XML.hash(reference);
      if (code != null) {
       //Keep it.
        pushBack.append(code);
      } else {
        throw new IOException("Invalid/Unknown reference '&" + reference + ";'");
      }
    } else {
     //Did not terminate properly! 
     //Perhaps an & on its own or a malformed reference.
     //Either way, escape the &
      pushBack.append("&").append(reference).append((char) ch);
    }
  }

  private void given(CharSequence s, int wanted, int got) {
   //Keep track of what we've given them.
    red.append(s);
    given += got;
    log.finer("Given: [" + wanted + "," + got + "]-" + s);
  }

  @Override
  public int read() throws IOException {
    StringBuilder s = read(1);
    given(s, 1, 1);
    return s.length() > 0 ? s.charAt(0) : -1;
  }

  @Override
  public int read(byte[] data, int offset, int length) throws IOException {
    int n = 0;
    StringBuilder s = read(length);
    for (int i = 0; i < Math.min(length, s.length()); i++) {
      data[offset + i] = (byte) s.charAt(i);
      n += 1;
    }
    given(s, length, n);
    return n > 0 ? n : -1;
  }

  @Override
  public String toString() {
    String s = red.toString();
    String h = "";
   //Hex dump the small ones.
    if (s.length() < 8) {
      Separator sep = new Separator(" ");
      for (int i = 0; i < s.length(); i++) {
        h += sep.sep() + Integer.toHexString(s.charAt(i));
      }
    }
    return "[" + given + "]-\"" + s + "\"" + (h.length() > 0 ? " (" + h + ")" : "");
  }

  private boolean isWhiteSpace(int ch) {
    switch (ch) {
      case ' ':
      case '\r':
      case '\n':
      case '\t':
        return true;
    }
    return false;
  }

  private boolean isAlphaNumeric(int ch) {
    return ('a' <= ch && ch <= 'z') 
        || ('A' <= ch && ch <= 'Z') 
        || ('0' <= ch && ch <= '9');
  }
}
1
追加された

あなたが持っているのはそのキャラクターは、データが表現する意味に依存します。 (明らかに ACK ですが、それはファイルで表現するのが奇妙です...)しかし、重要なのはXMLを無効にするという点がポイントです。XMLでその文字を表すことはできません。

xml 1.0仕様、セクション2.2

文字範囲

 /*サロゲートブロック、FFFE、およびFFFFを除くすべてのUnicode文字。 * /
Char :: =#x9 | #xA | #xD | [#x20-#xD7FF]
                     | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
 

U + 0009(タブ)、U + 000A(改行)、U + 000D(キャリッジリターン)以外のU + 0020未満のUnicode値は除外されています。

戻ってくるデータに影響がある場合は、有効なXMLを返すように変更する必要があります。そうでない場合は、XMLとして解析する前にいくつかの前処理を行う必要があります。あなたがあなたの状況でどのような意味を持っているかによって、望ましくない制御文字で何をしたいのかが決まります。

0
追加された