创建RSS Feed XML文件时出错 - Java

时间:2010-06-02 22:37:57

标签: java xml rss

我正在尝试使用java创建一个RssFeed 这是我使用的课程

import com.rssFeed.domain.RSS;
import com.rssFeed.domain.RSSItem;
import java.io.FileOutputStream;
import java.util.Iterator;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;



public class RssBuilder {

  private static String XML_BLOCK = "\n";
  private static String XML_INDENT = "\t";

  public static void BuildRss(RSS rss, String xmlfile) throws Exception {

      XMLOutputFactory output = XMLOutputFactory.newInstance();        
      XMLEventWriter writer = output.createXMLEventWriter(new FileOutputStream(xmlfile));
      try
      {                  
        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
        XMLEvent endSection = eventFactory.createDTD(XML_BLOCK);

        StartDocument startDocument = eventFactory.createStartDocument();
        writer.add(startDocument);
        writer.add(endSection);

        StartElement rssStart = eventFactory.createStartElement("", "", "rss");
        writer.add(rssStart);
        writer.add(eventFactory.createAttribute("version", "2.0"));
        writer.add(endSection);

        writer.add(eventFactory.createStartElement("", "", "channel"));
        writer.add(endSection);

        createNode(writer, "title", rss.getTitle());
        createNode(writer, "description", rss.getDescription());
        createNode(writer, "link", rss.getLink());
        createNode(writer, "dateCreated", rss.getDateCreated().toString());

        createNode(writer, "language", rss.getLanguage());
        createNode(writer, "pubDate", rss.getPubDate().toString());
        createNode(writer, "dateModified", rss.getDateModified().toString());
        createNode(writer, "dateModified", rss.getDateModified().toString());
        createNode(writer, "pubDate", rss.getPubDate().toString());
        createNode(writer, "lastBuildDate", rss.getLastBuildDate().toString());
        createNode(writer, "language", rss.getLanguage().toString());
        createNode(writer, "rating", rss.getRating().toString());

        Iterator<RSSItem> iterator = rss.getRssItems().iterator();
        while (iterator.hasNext()) {
          RSSItem entry = iterator.next();
          writer.add(eventFactory.createStartElement("", "", "item"));
          writer.add(endSection);

          createNode(writer, "title", entry.getTitle());
          createNode(writer, "description", entry.getDescription());
          createNode(writer, "link", entry.getLink());
          createNode(writer, "dateCreated", entry.getDateCreated().toString());
          createNode(writer, "pubDate", entry.getDateModified().toString());
          writer.add(eventFactory.createEndElement("", "", "item"));
          writer.add(endSection);
        }

        writer.add(endSection);
        writer.add(eventFactory.createEndElement("", "", "channel"));
        writer.add(endSection);
        writer.add(eventFactory.createEndElement("", "", "rss"));

        writer.add(endSection);
        writer.add(eventFactory.createEndDocument());
        writer.close();
      }
      catch(Exception e)
      {
          writer.close();
      }
  }

  private static void createNode(XMLEventWriter eventWriter, String name, String value)throws XMLStreamException {

      XMLEventFactory eventFactory = XMLEventFactory.newInstance();
        XMLEvent endSection = eventFactory.createDTD(XML_BLOCK);
        XMLEvent tabSection = eventFactory.createDTD(XML_INDENT);

        StartElement sElement = eventFactory.createStartElement("", "", name);
        eventWriter.add(tabSection);
        eventWriter.add(sElement);

        Characters characters = eventFactory.createCharacters(value);
        eventWriter.add(characters);

        EndElement eElement = eventFactory.createEndElement("", "", name);
        eventWriter.add(eElement);
        eventWriter.add(endSection);
  }

}

但我收到以下错误

type Exception report

message

descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.xml.stream.XMLStreamException: Can not write DOCTYPE declaration (DTD) when not in prolog any more (state 2; start element(s) written)

root cause

javax.xml.stream.XMLStreamException: Can not write DOCTYPE declaration (DTD) when not in prolog any more (state 2; start element(s) written)
这是什么意思?

2 个答案:

答案 0 :(得分:1)

这意味着代码试图在DTD信息在XML文档中合法的地方之外写入DTD信息。

DTD(文档类型定义)描述了文档的允许结构(以及可能的内容)。我认为DTD信息必须出现在文档的根节点之前(在prolog中)。

查看您提供的代码,我认为有很多地方将endSection变量写入编写器。 endSection看起来像包含DTD声明。尝试删除在第一个之后写入endSection的行。

答案 1 :(得分:0)

我的回答是Brabster的扩展

XMLEvent endSection = eventFactory.createDTD(XML_BLOCK);
StartDocument startDocument = eventFactory.createStartDocument();
writer.add(startDocument);
writer.add(endSection);

对于StartDocumentendSection是正确的。但

StartElement rssStart = eventFactory.createStartElement("", "", "rss");
writer.add(rssStart);
writer.add(eventFactory.createAttribute("version", "2.0"));
writer.add(endSection); 
// --> here we will writer like this
writer.add(eventFactory.createCharacters("\n"));