23

Вопрос по xml, java – Почему я получаю эту ошибку Преждевременный конец файла?

Я пытаюсь разобрать иXML response, но я с треском провалился. Я думал изначально чтоxml просто не был возвращен в ответе, поэтому я разработал приведенный ниже код с прямой ссылкой на мойxml подать онлайн. Я могу напечататьXML на экран без проблем. Однако когда я вызываю мой метод синтаксического анализа, я получаюPremature end of file.

Это работает, если я передам URL напрямую:

  • builder.parse("");

но не удается, когда я передал InputStream:

  • builder.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);
    }
    

Ошибки, которые я получаю:

    [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)
  • Этот ответ так полезен. Не всегда вы можете отлаживать или изменять код, если получаете ошибку от стороннего инструмента. Я был в той же самой ситуации, когда XML, который не должен был быть пустым, фактически был пустым. Спасибо и мой +1.

    от
  • Я удалил инструкцию readLine (). Но я все еще получаю ту же ошибку. Если я предоставлю прямую ссылку на XML, это работает. Если я пытаюсь обработать с использованием connection.getInputStream (), если выдает эту ошибку.

    от Fabii
  • Почему вы делаете POST, но не отправляете какие-либо данные?

    от user207421
  • @Fabii В чем проблема с возвращаемым потоком? Я хочу знать, потому что у меня та же проблема.

    от
  • Вы правы, вы не можете прочитать входной поток дважды. Хорошее объяснение также здесь:danielschneller.com/2008/01/…

    от
  • Была также проблема с потоком, который возвращался. Задача решена.

    от Fabii
  • @sbridges, очень мило объяснил!

    от
  • У вас есть файл XML, который вы пытаетесь проанализировать. Преждевременное завершение файла указывает на то, что ваш XML-файл не был завершен, так как вы используете URL-соединение здесь, я подозреваю, что проблемы с сетью. Лучший способ решить эту проблему - перехватить этот XML-файл с помощью инструментов Wireshark или монитора TCP, а затем проверить, завершен ли он.

    от NiranjanBhat
  • @NiranjanBhat. Да, XMl является полным и действительным. Я разобрал этот xml с прямой ссылкой. Кажется, ошибка возникает только при использовании InputStream.

    от Fabii
  • 28

    Когда вы делаете это,

    while((inputLine = buff_read.readLine())!= null){
            System.out.println(inputLine);
        }
    

    Вы потребляете все в instream, поэтому instream пуст. Теперь, когда попытаться сделать это,

    Document doc = builder.parse(instream);
    

    Разбор не удастся, потому что вы передали ему пустой поток.

  • 2

    Для тех, кто достиг этого поста для ответа:

    This happens mainly because the InputStream the DOM parser is consuming is empty

    Так что в том, что я столкнулся, могут быть две ситуации:

    The InputStream you passed into the parser has been used and thus emptied. The File or whatever you created the InputStream from may be an empty file or string or whatever. The emptiness might be the reason caused the problem. So you need to check your source of the InputStream.

  • 2

    Вы получаете ошибку

    потому что SAXBuilder недостаточно интеллектуален, чтобы иметь дело с «пустыми состояниями». Так выглядит как минимум<xml ..> объявление, и когда это вызывает ответ без данных, он создает исключение, которое вы видите, а не сообщать о пустом состоянии.

  • 1

    Я столкнулся с той же ошибкой и смог легко найти проблему

    зарегистрировав исключение:

    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);
        }
    });
    

    Или, вместо регистрации ошибки, вы можетеthrow это иcatch это где вы обрабатываете записи, так что вы можете распечатать саму запись, чтобы получить более точную информацию об ошибке.