java – 如果在输入文件中没有指定一个SAX解析器,如何强制使用DT
发布时间:2020-12-14 16:26:27 所属栏目:Java 来源:网络整理
导读:如果在输入文档中没有任何文字类型的情况下解析文档时,如何强制使用SAX解析器(特别是 Java中的Xerces)来使用DTD?这是甚么可能吗? 以下是我的场景的更多细节: 我们有一堆XML文档符合由多个不同系统生成的相同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 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |