2011-09-13 16 views
0

私はアンドロイドデバイス用にJavaとSAXを使用してXMLファイルを解析しようとしています。私はインターネットから取得し、それを解析しているときに、ExpatExceptionが発生しています。文字「é」の整形式ではありません(無効なトークン)。 xmlファイル内のすべてのスペシャル文字を変更することなく、それらの文字を処理する方法はありますか?SAX処理の特殊文字

編集: ここは私のSDカードにファイルを書き込むコードの一部です。ここで

File SDCardRoot = Environment.getExternalStorageDirectory(); 
      File f = new File(SDCardRoot,"edt.xml"); 
      f.createNewFile(); 
      FileOutputStream fileOutput = new FileOutputStream(f); 
      InputStream inputStream = urlConnection.getInputStream(); 


      byte[] buffer = new byte[1024]; 
      int bufferLength = 0; 
      while ((bufferLength = inputStream.read(buffer)) > 0) { 
       fileOutput.write(buffer, 0, bufferLength); 
      } 

      fileOutput.close(); 

は私のxmlの一部である:ここ

<?xml version="1.0" encoding="iso-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="ttss.xsl"?> 

<timetable> 
<option combined="0" totalweeks="0" showemptydays="0" dayclass="reverse"> 
<link href="g56065.xml" class="xml">Imprimer</link> 
<link href="g56065.pdf" class="pdf">Version PDF</link> 
<weeks>Semaines</weeks> 
<dates>Dates</dates> 
<week>Semaine</week> 
<date>Date</date> 
<all>Toutes les semaines</all> 
<notes>Remarques</notes> 
<id>ID</id> 
<tag>Champs Libre</tag> 
<footer>Publié le 10/09/2011 22:14:28</footer> 
... </timetable> 

は、解析コードである:ここ

public class ParserSemaines extends DefaultHandler { 
    private final String SEMAINE = "span"; 
    private final String DESCRIPTION = "description"; 
    private ArrayList<Semaine> semaines; 
    private boolean inSemaine; 
    private Semaine currentSemaine; 
    private StringBuffer buffer; 
    @Override 
    public void processingInstruction(String target, String data) throws SAXException { 
     super.processingInstruction(target, data); 
    } 
    public ParserSemaines() { 
     super(); 
    } 

    @Override 
    public void startDocument() throws SAXException { 
     super.startDocument(); 
     semaines = new ArrayList<Semaine>(); 
    } 

    @Override 
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { 
     buffer = new StringBuffer(); 
     if (localName.equalsIgnoreCase(SEMAINE)){ 
      this.currentSemaine = new Semaine(); 
      this.currentSemaine.setDate(attributes.getValue("date")); 
      this.inSemaine = true; 
     } 
     if(localName.equalsIgnoreCase(DESCRIPTION)){ 
      this.currentSemaine.setDescription(buffer.toString()); 
     } 
    } 

    @Override 
    public void endElement(String uri, String localName, String name) throws SAXException { 
     if (localName.equalsIgnoreCase(SEMAINE)){ 
      this.semaines.add(currentSemaine); 
      this.inSemaine = false; 
     } 
    } 

    public void characters(char[] ch,int start, int length) throws SAXException{ 
     String lecture = new String(ch,start,length); 
     if(buffer != null) buffer.append(lecture); 
    } 

    public ArrayList<Semaine> getData(){ 
     return semaines; 
    } 
} 

は、私は、パーサーを呼び出すために使用するコードです:

SAXParserFactory fabrique = SAXParserFactory.newInstance(); 
     SAXParser parseur = null; 
     ArrayList<Semaine> semaines = null; 
     try { 
      parseur = fabrique.newSAXParser(); 
      DefaultHandler handler = new ParserSemaines(); 
      File f = new File(Environment.getExternalStorageDirectory(),"edt.xml"); 
      parseur.parse(f, handler); 
      semaines = ((ParserSemaines) handler).getData(); 
     } 

その他のコード部分が必要かどうか質問します。

チェックした後、SDカードのxmlファイルに「é」が「�」と表示されます。 それは問題であるはずですが、なぜ私は何の手がかりも持っていません。 私もURIと解析しようとしましたが、私はいつも同じ例外を何も変えません。

+0

SAXパーサーは、非ASCII文字を問題なく処理する必要があります。あなたのコードとあなたのXMLの例を表示してください。 – parsifal

+0

1. XMLファイルが正しくエンコードされていないか、2. XMLファイルがHTTPヘッダーで示された文字エンコーディングでインターネット上で正しく提供されていて、ファイルをローカルに保存するときにその情報が失われた。 –

+0

このコードでは、データを生のバイトとしてコピーしているため、XMLのエンコーディングを混同することはできません。解析コードを表示する必要があります。 –

答えて

1

私は最終的に解決策を見つける。代わりにSAXparderを使用しての は、私はあなたが私を提供するすべての助けを

android.util.Xml.parse(InputStream,Xml.Encoding.ISO_8859_1, DefaultHandler); 

みんなありがとうを使用しています。

0

エンコードに問題がある可能性があります。それをISO-8859-1に変更してみてください。

<?xml version="1.0" encoding="ISO-8859-1"?> 

や、あなたのコードでは、使用:あなたのxml試みで

inputSource.setEncoding("ISO-8859-1"); 
+0

私のXMLでは、エンコーディングが正しく設定されています。私はinputSourceを使用していません。どこで使うべきですか? – Alexis

1

SDカード内のxmlファイルは "として "E" を示していることを表示されます確認した後、 � "。

これはエンコードの問題を示しています。

投稿したコードは、URLからファイルへの正しいバイト単位のコピーであるように見えるので、ファイルはURLから取得した内容を正確に表す必要があります。つまり、サーバーからの応答がISO-8859-1でない可能性があります。

  • Content-Typeヘッダ:

    私の次のステップは、全体の応答を調べるためのツールなどFiddlerを使用するに特に注意を払ってすることです。別の文字セットがある場合は、その情報をパーザに渡したり、手動で変換したりする必要があります。

  • 返される実際のバイト数。あなたが知っている限り、の両方 Content-TypeとXMLプロローグが存在する可能性があります。ファイルが本当にISO-8859-1の場合、アクセント付きのeのバイト値は0xE9になります。コンテンツが実際にUTF-8である場合、2バイトのシーケンス0xC3 0xA9が存在するはずです(hereを参照)。 3バイトのシーケンスが表示されていますが、これは意味をなさないものです。しかし、ソースを確認するのが最善です。

また、あなたがSAXパーサに渡す前に、文字列にファイルを変換ないていることを確認します。


は、参考のために:私はOPのURLに接続し、最小限のSAXパーサーに直接その接続を渡し、最小限のプログラムを書きました。それは間違いなく実行されたようだ。また、DOMパーサーを使用して、少なくともルート要素が正しく解析されていることを確認しました。

public static void main(String[] argv) 
throws Exception 
{ 
    URL url = new URL("http://www.disvu.u-bordeaux1.fr/et/edt_etudiants2/Master/Semestre1/g56065.xml"); 
    InputStream in = url.openConnection().getInputStream(); 

    SAXParserFactory spf = SAXParserFactory.newInstance(); 
    SAXParser parser = spf.newSAXParser(); 
    parser.parse(in, new DefaultHandler()); 
    System.out.println("parse successful"); 
} 
+0

はここにフィッダー結果、応答ヘッダー: HTTP/1.0 200 OK 日付:Wed、14 Sep 2011 16:01:44 GMT サーバー:Apache 最終更新日:水曜日、2011年9月14日15:18:40 GMT のETag: "da80c9-1e634-46611400" -範囲を受け入れ:バイト のContent-Lengthを:124468 接続:クローズ のContent-Type:アプリケーション/ xmlの 私がチェックし、 "E" は、六角結果に効果的0xE9です。 私が得た唯一の解決策は、処理に時間がかかる場合でもすべて "é"を "e"に変更しているような気がします。 xmlファイルのURLは次のとおりです。 http://www.disvu.u-bordeaux1.fr/et/edt_etudiants2/Master/Semestre1/g56065.xml – Alexis

+0

@Alexis - 私は困惑していると認めなければなりません。あなたのリンクを読み込んでいますが、内容はISO-8859-1のエンコーディングであるようです。すべてのヘッダーが正しく見える。そして、あなたのコードは、単純なバイト単位のコピーに見えます。 – parsifal

+0

SDカードのファイルが別のバイトを表示していることが奇妙なことがわかりました。単純に端末に送信していますか、または16進ダンププログラムを使用していますか?前者の場合は、バイトがファイル内で実際に展開されていることを確認するために後者を試してください。 – parsifal