Por que estou recebendo este erro prematuro fim de arquivo?

Estou a tentar analisar e ... mas estou a falhar miseravelmente. Pensei inicialmente que o xml simplesmente não estava sendo devolvido na resposta, então eu criei o código abaixo com um link direto para o meu arquivo xml on-line. Eu sou capaz de imprimir o XML para tela sem problemas. No entanto, quando eu chamo o meu método de análise, eu recebo fim prematuro do arquivo.

funciona se eu passar o URL directamente:

    Construtor.processar("");
Mas falha quando passei por um Fluxo interno:

  • Construtor.parse (connection.getInputStream ();

      try {
        URL url = new URL(xml);
        URLConnection uc =  url.openConnection();
        HttpURLConnection  connection = (HttpURLConnection )uc;
    
        connection.setDoInput(true);
        connection.setDoOutput(true);
    
        InputStream instream;
        InputSource source;
        //get XML from InputStream
        if(connection.getResponseCode()>= 200){
            connection.connect();       
            instream = connection.getInputStream();         
            parseDoc(instream);     
        }
        else{
            instream = connection.getErrorStream();
        }
    
    
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    
    
     static void parseDoc(InputStream instream) throws ParserConfigurationException,
     SAXException, IOException{
    
    
      BufferedReader buff_read = new BufferedReader(new InputStreamReader(instream,"UTF-8"));
        String  inputLine = null;
    
        while((inputLine = buff_read.readLine())!= null){
            System.out.println(inputLine);
        }
    
      DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
      factory.isIgnoringElementContentWhitespace();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document doc = builder.parse(instream);
    }
    

os erros que estou a receber:

    [Fatal Error] :1:1: Premature end of file.
org.xml.sax.SAXParseException: Premature end of file.
    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)
    at com.ameba.api.network.MainApp.parseDoc(MainApp.java:78)
    at com.ameba.api.network.MainApp.main(MainApp.java:41)
Author: MLavoie, 2012-04-05

4 answers

Quando fizeres isto,
while((inputLine = buff_read.readLine())!= null){
        System.out.println(inputLine);
    }
Consumes tudo no instream, por isso o instream está vazio. Agora, quando tentar fazer isso,
Document doc = builder.parse(instream);

A análise falhará, porque você passou por ela um riacho vazio.

 27
Author: sbridges, 2012-04-05 05:36:36

Para aqueles que chegaram a este post para Resposta:

Isto acontece principalmente porque o {[[0]} que o analisador DOM está a consumir está vazio

Então, no que encontrei, pode haver duas situações:
  1. o {[[0]} que passou para o analisador foi usado e, portanto, esvaziado.
  2. o File ou o que quer que tenha criado o InputStream pode ser um ficheiro vazio ou uma cadeia de caracteres, ou seja lá o que for. O vazio pode ser a razão que causou o problema. Então você precisa verificar o seu origem do {[[0]}.
 2
Author: cinqS, 2017-08-16 06:46:23

Encontrei o mesmo erro, e pude facilmente encontrar qual era o problema ao registar a excepção:

documentBuilder.setErrorHandler(new ErrorHandler() {
    @Override
    public void warning(SAXParseException exception) throws SAXException {
        log.warn(exception.getMessage());
    }

    @Override
    public void fatalError(SAXParseException exception) throws SAXException {
        log.error("Fatal error ", exception);
    }

    @Override
    public void error(SAXParseException exception) throws SAXException {
        log.error("Exception ", exception);
    }
});

Ou, em vez de registar o erro, você pode throw isto e catch aquilo onde lida com os itens, para que possa imprimir o item em si para obter uma melhor indicação sobre o erro.

 1
Author: Maroun, 2015-03-01 08:57:18
Você está recebendo o erro porque o SAXBuilder não é inteligente o suficiente para lidar com "estados em branco". Então ele procura pelo menos uma declaração {[[0]}, e quando isso provoca uma resposta de dados no cria a exceção que você vê em vez de relatar o estado vazio.
 1
Author: mist42nz, 2017-06-05 01:45:53