gpt4 book ai didi

java - 解析没有文档开始和结束标记的 XML

转载 作者:行者123 更新时间:2023-12-01 14:50:17 24 4
gpt4 key购买 nike

我正在解析一个无法使用 SAX 解析器从 Internet 更改的文档。当文档格式如下时,它工作得很好:

<outtertag>
<innertag>data</innertag>
<innerag>moreData</innertag>
</outtertag>

但是,我进行了某些调用,其中 XML 的格式没有外部标记,因此我基本上只得到一个数据列表,如下所示:

  <innertag>data</innertag>
<innerag>moreData</innertag>

这对我来说似乎很愚蠢,但我无法选择 XML 的格式,而且目前无法更改。问题在于,似乎 SAX 解析器一碰到第一个结束内部标记就触发了 endDocument 事件。

我有一个相当hacky的解决方案,将InputStream转换为字符串,在其周围添加标签,然后将其转换回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



}
}

而且,如果重要的话,这是我正在使用的黑客代码,但感觉不对,但它有效:

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);

最佳答案

我想说你现在所做的已经是你能得到的最好的了。需要考虑改进的一件事是流 -> 字符串 -> 流转换,特别是当文档很大时。你可以使用像 Guava 的 ByteStreams.join() 这样的东西,它允许您将流而不是字符串连接在一起。类似于以下内容:

import com.google.common.io.*;
import java.io.*;

public class ConcatenateStreams {
public static void main(String[] args) throws Exception {
InputStream malformedXmlContent = externalXmlStream();
InputSupplier<InputStream> joined = ByteStreams.join(
inputSupplier("<root>"),
inputSupplier(malformedXmlContent),
inputSupplier("</root>"));
ByteStreams.copy(joined, System.out);
}

private static InputStream externalXmlStream() {
return new ByteArrayInputStream("<foo>5</foo><bar>10</bar>".getBytes());
}

private static InputSupplier<InputStream> inputSupplier(final String text) {
return inputSupplier(new ByteArrayInputStream(text.getBytes()));
}

private static InputSupplier<InputStream> inputSupplier(final InputStream inputStream) {
return new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
return inputStream;
}
};
}
}

输出:

<root><foo>5</foo><bar>10</bar></root>

关于java - 解析没有文档开始和结束标记的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14948146/

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