使用StAX从一个XML文档读取DTD并写入另一个XML文档

时间:2014-12-04 19:54:36

标签: java xml stax xml-dtd dtd-parsing

所以我正在使用StAX对一系列XML文档进行一些数据清理。我想基本上阅读文档并吐出完全相同的文档,遗漏了一些标签。我遇到的问题是我没有输出有效的XML。

您可以在左侧看到我的输出,在右侧[此处](http://imgur.com/a/oFxZd)看到原始文档。底部的图像也是xmllint -valid的输出。正如您所看到的那样,没有找到DTD,并且文档末尾还有额外的内容。

我实现编写器的代码就是这个

public XMLEventWriter setUpWriter(File blah) throws FileNotFoundException,                XMLStreamException {
    newFileName = thef.getName().substring(0, thef.getName().indexOf("_") + 1);

    try {
        writer = outputFactory
                .createXMLEventWriter(new FileOutputStream(newFileName + "mush.xml"), "UTF-8");

    } catch (XMLStreamException ex) {
        ex.printStackTrace();
        System.out.println("There was an XML Stream Exception, whatever that means for writer");
    }
    //outputFactory.setProperty("escapeCharacters", false);
    eventFactory = XMLEventFactory.newInstance();
    StartDocument startDocument = eventFactory.createStartDocument();

    writer.add(startDocument);
    //writer.add("<!DOCTYPE DjVuXML>");
    return writer;
}

这是我处理实际写作的代码。

 if (event.isStartElement()) { //first it looks for start elements
            StartElement se = event.asStartElement();
            if ("OBJECT".equals(se.getName().getLocalPart())) {
                writer.add(se);
            } else if ("MAP".equals(se.getName().getLocalPart())) {
                writer.add(se);
    } else if ("PARAM".equals(se.getName().getLocalPart())) {
                writer.add(se);
            } else if ("LINE".equals(se.getName().getLocalPart())) {
                writer.add(se);
            } else if ("DjVuXML".equals(se.getName().getLocalPart())) {
                writer.add(se);
            }else if ("WORD".equals(se.getName().getLocalPart())) {
                    word.text = reader.getElementText();

                    EndElement wordEnd = eventFactory.createEndElement("", "", "WORD");
                    writer.add(se);
                    Characters characters = eventFactory.createCharacters(word.text);
                    writer.add(characters);
                    writer.add(wordEnd);
                }

            }

        } else if (event.isEndElement()) {

            EndElement ee = event.asEndElement();
            if ("MAP".equals(ee.getName().getLocalPart())) {
                writer.add(ee);

            } else if ("DjVuXML".equals(ee.getName().getLocalPart())) {
                writer.add(ee);
            } else if ("LINE".equals(ee.getName().getLocalPart())) {
                writer.add(ee);
            }
            else if ("BODY".equals(ee.getName().getLocalPart())) {
                writer.add(ee);
            }
        }

    }
    writer.flush();
    writer.close();

现在我们已经解决了这个问题,我的问题是双重的:

1)我的输出无效,因为它缺少DTD吗?

1a)如果是,我如何包含DTD?即使没有告诉我,这一直困扰着我

2)如果它不是DTD那么我该怎样才能使这个东西有效。

感谢您的帮助!!

1 个答案:

答案 0 :(得分:0)

  

1)我的输出无效,因为它缺少DTD吗?

简短回答:理论上,也许是,也许不是;在实践中,是的。

在XML规范中,有效性为defined因此:

  

如果XML文档具有关联的文档类型声明,并且文档符合其中表达的约束,则该文档有效。

当且仅当文档服从DTD中的约束时,一些读者认为文档对DTD有效。从这个意义上说,没有文档类型声明的文档可以对某些指定的DTD有效,并且具有文档类型声明的文档可以对其文档类型声明中指定的DTD或任何其他指定的DTD有效。或视情况而定无效。

其他读者将此定义视为文档无法有效(至少在严格意义上),除非它具有文档类型声明,并且有效性问题仅对指定的文档类型定义有意义通过文件的文件类型声明。

实际上,除非您告诉验证解析器在哪里找到要验证的DTD,否则解析器别无选择,只能采取第二个更严格的视图。如果无法找到DTD,它如何验证文档? (有些验证解析器接受用于指向DTD的运行时参数,而其他解析器则不接受。)

  

1a)如果是,我如何包含DTD?即使没有告诉我,这一直困扰着我

the JavaDocs开始,对于StAX参考实现,看起来好像writeDTD(string)是你的朋友。

  

2)如果它不是DTD那么我该怎样才能使这个东西有效。

如果您收到有关&#34; exta内容&#34;的消息您的输出似乎不仅无效,而且格式不正确。首先检查并修复它。

额外内容的可能原因&#34;错误消息是您要么过早地关闭了根元素,要么根本没有根元素。