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



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

你可以在左边看到我的输出,在右边看到原始文档[这里](https://i.stack.imgur.com/aOptO.jpg(。底部的图像也是 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( 我的输出是否因为缺少 DTD 而无效?

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

在 XML 规范中,有效性定义如下:

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

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

其他读者认为这个定义意味着一个文档不能有效(至少在严格意义上(,除非它有一个文档类型声明,并且有效性问题只对文档的文档类型声明指定的文档类型定义有意义。

实际上,除非您告诉验证分析器在何处可以找到要验证的 DTD,否则分析器别无选择,只能采用第二种更严格的视图。 如果找不到 DTD,如何验证文档? (某些验证分析器接受用于指向 DTD 的运行时参数,而其他分析器则不接受。

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

从StAX参考实现的JavaDocs来看,writeDTD(string)似乎是你的朋友。

2(如果不是DTD,那么我到底如何让这个东西有效。

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

出现"额外内容"错误消息的可能原因是您过早关闭了根元素,或者根本没有根元素。

最新更新