java – 如果在输入文件中没有指定一个SAX解析器,如何强制使用DTD?
|
如果在输入文档中没有任何文字类型的情况下解析文档时,如何强制使用SAX解析器(特别是 Java中的Xerces)来使用DTD?这是甚么可能吗? 以下是我的场景的更多细节: 我们有一堆XML文档符合由多个不同系统生成的相同DTD(我不能更改).其中一些系统在其输出文档中添加了一个doctype,另一些则不会.有些使用命名字符实体,有些不行.有些使用命名字符实体,而不声明一个doctype.我知道这不是犹太教,但这是我必须合作的. 我正在使用需要在Java中解析这些文件的系统.目前,它正在处理上述情况,首先将XML文档作为流读取,尝试检测是否定义了一个doctype,如果尚未存在,则添加一个doctype声明.问题是这个代码是错误的,我想用更清洁的东西替换它. 文件很大,所以我不能使用基于DOM的解决方案.我也试图解决字符实体,所以它不利于使用XML模式. 如果你有一个解决方案,你可以直接发布,而不是链接到它?如果在未来有一个正确的解决方案与死链接,它不会做堆栈溢出很好. 解决方法我认为设置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
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
