gpt4 book ai didi

java - 如果输入文件中未指定 DTD,我如何强制 SAX 解析器使用 DTD?

转载 作者:搜寻专家 更新时间:2023-10-30 21:34:39 28 4
gpt4 key购买 nike

在输入文档中没有 any 文档类型的情况下,如何在解析文档时强制 SAX 解析器(特别是 Java 中的 Xerces)使用 DTD?这可能吗?

以下是我的场景的更多详细信息:

我们有一堆符合相同 DTD 的 XML 文档,这些文档由多个不同的系统生成(我无法更改)。其中一些系统将文档类型添加到它们的输出文档中,而另一些则没有。有些使用命名字符实体,有些则不使用。 有些使用命名字符实体而不声明文档类型。我知道这不符合犹太洁食标准,但这是我必须使用的。

我正在开发需要用 Java 解析这些文件的系统。目前,它通过首先将 XML 文档作为流读取来处理上述情况,尝试检测它是否定义了文档类型,如果不存在则添加文档类型声明。问题是这段代码有问题,我想用更干净的代码替换它。

文件很大,所以我不能使用基于 DOM 的解决方案。我也在尝试解析字符实体,因此使用 XML 架构无济于事

如果您有解决方案,请直接发布而不是链接到它吗?如果将来有一个带有死链接的正确解决方案,它对 Stack Overflow 没有太大好处。

最佳答案

如果文档没有,我认为设置 DOCTYPE 是不明智的方法。可能的解决方案是写一个假的,就像你已经做的那样。如果您使用的是 SAX,则可以使用这个伪造的 InputStream 和伪造的 DefaultHandler 实现。 (仅适用于 latin1 单字节编码)

我知道这个解决方案也很丑陋,但它只有一个适用于大数据流。

这是一些代码。

private enum State {readXmlDec, readXmlDecEnd, writeFakeDoctipe,  writeEnd};

private class MyInputStream extends InputStream{

private final InputStream is;
private StringBuilder sb = new StringBuilder();
private int pos = 0;
private String doctype = "<!DOCTYPE register SYSTEM \"fake.dtd\">";
private State state = State.readXmlDec;

private MyInputStream(InputStream source) {
is = source;
}
@Override
public int read() throws IOException {
int bit;

switch (state){
case readXmlDec:
bit = is.read();
sb.append(Character.toChars(bit));
if(sb.toString().equals("<?xml")){
state = State.readXmlDecEnd;
}
break;
case readXmlDecEnd:
bit = is.read();
if(Character.toChars(bit)[0] == '>'){
state = State.writeFakeDoctipe;
}
break;
case writeFakeDoctipe:
bit = doctype.charAt(pos++);
if(doctype.length() == pos){
state = State.writeEnd;
}
break;
default:
bit = is.read();
break;
}
return bit;
}

@Override
public void close() throws IOException {
super.close();
is.close();
}
}

private static class MyHandler extends DefaultHandler {

@Override
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
System.out.println("resolve "+ systemId);
// get real dtd
InputStream is = ClassLoader.class.getResourceAsStream("/register.dtd");
return new InputSource(is);
}

... // rest of code
}

关于java - 如果输入文件中未指定 DTD,我如何强制 SAX 解析器使用 DTD?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2412862/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com