我正在解析一个无法使用 SAX 解析器从 Internet 更改的文档。当文档格式如下时,它工作得很好:
<outtertag>
<innertag>data</innertag>
<innerag>moreData</innertag>
</outtertag>
但是,在某些调用中,我会在没有外部标签的情况下对 XML 进行格式化,因此我基本上只得到了一个数据列表,如下所示:
<innertag>data</innertag>
<innerag>moreData</innertag>
这对我来说似乎很愚蠢,但我无法选择 XML 的格式,现在也无法更改。问题在于,SAX 解析器似乎在遇到第一个关闭内部标签时就命中了 endDocument 事件。
我有一个相当老套的解决方案,将 InputStream 转换为 String,在其周围添加标签,然后将其转换回 InputStream。它实际上以这种方式解析得很好。但是,肯定有更好的方法。我也不想写一个完整的解析器。除了缺少开始和结束标签之外,大多数标签都是相同的。
只是为了它,我将发布代码,但它是非常标准的 SAX 解析器。原文实际上是在解析大约 30 一些标签:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
MyHandler handler = new MyHandler();
xmlReader.setContentHandler(handler);
InputSource inputSource = new InputSource(url.openStream());
xmlReader.parse(inputSource);
}
catch (SAXException e) { e.printStackTrace(); }
catch (ParserConfigurationException e) { e.printStackTrace(); }
catch(Exception e) { e.printStackTrace(); }
}
private class MyHandler extends DefaultHandler {
private StringBuilder content;
public MyHandler() {
content = new StringBuilder();
}
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
content = new StringBuilder();
if(localName.equalsIgnoreCase("innertag")) {
//Doing stuff
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
//Doing stuff
}
public void characters(char[] ch, int start, int length)
throws SAXException {
content.append(ch, start, length);
}
public void endDocument() throws SAXException {
//When parsing the second type of document, hits this event almost immediately after parsing first tag
}
}
而且,如果重要的话,这是我正在使用的 hacky 代码,但感觉不对,但它有效:
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder sb = new StringBuilder("<tag>");
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
sb.append("</tag>");
String xml =sb.toString();
InputStream is = new ByteArrayInputStream(xml.getBytes());
InputSource source = new InputSource(is);
xmlReader.parse(source);