Even before I've been trying to find a convenient way to identify whether a parsing has stopped because of a character encoding problem. I'm attaching a sample (the main application entry is in "ParsingText.java"): it tries to parse an "UTF-8" encoding mislabeled document which is actually encoded using "ISO-8859-1" ("charter.xml"). Upon encountering he first non-ASCII character the reading fails and the parser throws |SAXParseException|... while I'm more convinced I should get an |IOException| type.

The problem is I have to detect specific exception messages to guess the problem is the one I'm looking for and those messages could easily change between parser versions and are surely different between different parser implementations. I think it would be nice if the whatever relevant underlying exception is initialized as |cause| of the |SAXParseException| being thrown so one can detect the problem in more Java natural way.

Something I've noticed when I provide a custom input stream of data ("TestStream.java"), when the reading from that stream throws |java.io.CharConversionException| it is not propagated as |IOException| but again a |SAXParseException| is thrown with its message containing the original exception message.

I've noticed the optimized Xerces readers already throw |java.io.CharConversionException| (|org.apache.xerces.impl.io.MalformedByteSequenceException|) upon character encoding problem and while I don't know why it is not propagated as general |IOException| (do you know why?), if they are initialized as |cause| of the |SAXParseException| being thrown I could do something like:

    XMLReader xmlReader;
    InputSource input;
    ...
    try {
        xmlReader.parse(input);
    } catch (CharConversionException ex) {
        /* encoding problem detected */
    } catch (IOException ex) {
        ...
    } catch (SAXException ex) {
        if (ex.getCause() instanceof CharConversionException) {
            /* encoding problem detected */
        }
    }

Then in interactive environment I could present a user with convenient options to retry the operation specifying different source encoding, for example.

Has this been considered before?

--
Stanimir
package net.example;

import java.io.IOException;
import java.net.URL;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

public class ParsingTest {

    public static void main(String[] args) {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        XMLReader xmlReader;
        try {
            xmlReader = spf.newSAXParser().getXMLReader();
        } catch (SAXException ex) {
            ex.printStackTrace();
            return;
        } catch (ParserConfigurationException ex) {
            ex.printStackTrace();
            return;
        }
        
        ErrorHandler errorHandler = new ErrorHandler() {
            public void warning(SAXParseException exception) {
                System.err.println("[warning] " + exception);
            }
            public void fatalError(SAXParseException exception) {
                System.err.println("[fatal] " + exception);
            }
            public void error(SAXParseException exception) {
                System.err.println("[error] " + exception);
            }
        };
        xmlReader.setErrorHandler(errorHandler);
        
        URL source = ParsingTest.class.getResource("charter.xml");
        InputSource input = new InputSource(source.toExternalForm());
                //new InputSource(new TestStream());
        
        try {
            xmlReader.parse(input);
        } catch (IOException ex) {
            System.err.println();
            ex.printStackTrace();
        } catch (SAXException ex) {
            System.err.println();
            ex.printStackTrace();
        }
    }

}
<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en-US">
<head>
  <title>Xerces Project Charter</title>
  <link rel="source" href="http://xerces.apache.org/xerces2-j/charter.html";
      title="Xerces Project Charter" />
</head>
<body>

<h1>Xerces Project Charter</h1>
<p>
The following charter applies to all Xerces projects.</p>

<h2>Introduction</h2>
<p>
Apache Xerces est un projet de collaboration de développement de logiciel 
consacré à fournir robuste, complet, à la commercial-qualité, et librement aux 
analyseurs disponibles de XML et aux technologies étroitement liées sur une 
grande variété de plateformes soutenant plusieurs langues. Ce projet est 
contrôlé dans le monde entier en coopération avec les divers individus (les 
experts indépendants et compagnie-filiales), qui emploient l'Internet pour 
communiquer, projeter, et développer le logiciel de XML et la documentation 
relative.</p>
<p>
Cette charte décrit brièvement la mission, l'histoire, l'organisation, et les 
processus du projet.</p>

<h2>Mission</h2>
<p>
Apache Xerces existe pour favoriser l'utilisation de XML. Nous regardons XML 
comme paradigme contraignant qui structure des données comme information, 
facilitant de ce fait l'échange, la transformation, et la présentation de la 
connaissance. La capacité de transformer des données brutes en information 
utilisable a le grand potentiel d'améliorer la fonctionnalité et l'utilisation 
des systèmes d'information. Nous avons l'intention d'établir librement des 
analyseurs disponibles de XML et des technologies étroitement liées afin 
d'engendrer de telles améliorations.</p>
<p>
Les analyseurs d'Apache Xerces soutiennent APIs standard (formel, de fait, ou 
proposé). Ils sont conçus pour être rendement élevé, fiable, et facile à 
employer. Pour faciliter la mise en communication facile des idées entre les 
langues, les api soutenus devraient être aussi semblables comme possible, donné 
les contraintes des langues et des architectures existantes. Des analyseurs 
d'Apache Xerces devraient également être conçus pour travailler efficacement 
avec l'autre Apache projette qu'affaire avec XML autant que possible.</p>
<p>
Nous croyons que la meilleure manière à autre ces buts est en ayant des 
individus et les sociétés collaborent sur la meilleure infrastructure, APIs, 
code, examinant, et des cycles de dégagement. Les composants doivent être 
fournisseur neutre et utilisable comme composants de noyau pour tous.</p>
<p>
Afin de réaliser une architecture logique entre les analyseurs d'Apache Xerces 
et d'autres composants et applications, des normes (formelles ou de fait) seront 
employées autant que possible pour des protocoles et APIs. Le cas échéant, des 
expériences et des leçons appriss sera rétroagi aux organismes de normalisation 
dans un effort d'aider au développement de ces normes. Nous encouragerons 
également l'innovation de nouveaux protocoles, d'APIs, et de composants afin de 
semer de nouveaux concepts pas encore définis par des normes.</p>

<div>...</div>		

</body>
</html>
package net.example;

import java.io.ByteArrayInputStream;
import java.io.CharConversionException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;


public class TestStream extends InputStream {

    private static final String SOURCE =
            "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
            + "<document>"
            + "<title>Sample Document</title>"
            + "<paragraph>"
            + "...";

    private InputStream mContent;

    public TestStream() {
        try {
            mContent = new ByteArrayInputStream(SOURCE.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException ueex) {
            throw new AssertionError(ueex);
        }
    }

    public int read() throws IOException {
        int ch = mContent.read();
        if (ch == -1) {
            throw new MyException();
        }
        return ch;
    }

}


class MyException extends CharConversionException {
        //extends IOException {
    
    private static final long serialVersionUID = 1L;

    MyException() {
        super("My Custom Exception");
    }

}


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to