2011-09-13 6 views
0

Java 및 SAX로 XML 파일을 안드로이드 장치로 구문 분석하려고합니다. 나는 인터넷에서 얻었고 구문 분석을하는 동안 문자 "é"에 올바른 형식 (유효하지 않은 토큰)이 아닌 ExpatException이 발생합니다. xml 파일의 모든 specials 문자를 변경하지 않고도 해당 문자를 처리 할 수 ​​있습니까?SAX 특수 문자 처리

편집 : 여기 내 코드에서 내 SDcard에 파일을 쓰는 부분입니다.

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(); 
     } 
: 여기
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; 
    } 
} 

내가 파서 전화를 걸 때 사용하는 코드입니다 : 여기
<?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> 

가 파싱 코드 : 여기
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의 일부입니다

다른 코드 부분이 필요한지 물어보십시오.

확인 후 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"?> 

또는 코드에서 사용 :

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

내 XML 인코딩이 올바르게 설정되어 있습니다. 나는 inputSource를 사용하지 않는다. 어디에서 사용해야합니까? – Alexis

1

이는 SD 카드에 XML 파일 "로"é "를 보여줍니다 것으로 보인다 확인하는 XML 시도에서

� ".

이것은 인코딩 문제를 나타냅니다.

게시 한 코드가 URL에서 파일로 올바른 바이트 단위로 복사되어 파일이 URL에서 가져온 내용을 정확히 나타내야합니다. 즉, 서버의 응답이 ISO-8859-1이 아닐 수 있습니다.

  • 콘텐츠-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 날짜 : 2011 년 9 월 14 일 수요일 16:01:44 GMT 서버 : Apache 마지막 수정 : Wed, 14 Sep 2011 15:18:40 GMT 있는 ETag : "da80c9-1e634-46611400" 동의-범위가 : 124,468 연결 : 닫기 의 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