gpt4 book ai didi

java - 使用 SAX : value cut in 2 halves 在 Java 中解析 XML

转载 作者:数据小太阳 更新时间:2023-10-29 02:02:55 25 4
gpt4 key购买 nike

我正在尝试读取一种基于 xml 的文件格式,在 JAVA 中使用 SAX 称为 mzXML。它携带部分编码的质谱数据(具有强度的信号)。

这是感兴趣的条目的样子(关于它有更多信息):

    <peaks ... >eJwBgAN//EByACzkZJkHP/NlAceAXLJAckeQ4CIUJz/203q2...</peaks>

可以下载在我的案例中强制执行错误的完整文件here .

其中一个条目中的字符串包含大约 500 个压缩和 base64 编码的 double 对(信号和强度)。我所做的是解压缩和解码,以获取值(解码未在下面的示例中显示)。这在小型数据集上一切正常。现在我使用了一个更大的,但遇到了一个我不明白的问题:

过程characters(ch,start,length) 不会读取前面显示的行中的完整条目。 length-value 似乎太小了。

我没有看到这个问题,当我刚刚将 peaks 条目打印到控制台时,因为有很多字母而且我没有意识到字母丢失了。但是解压失败,信息丢失。当我重复运行这个程序时,它总是在同一点中断同一行而不给出任何异常。如果我通过例如更改 mzXML 文件删除扫描,它会在不同的位置中断。我通过查看 currentValue

的内容,在 character() 过程中使用断点发现了这一点

这是重述问题所必需的代码段:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;

import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ReadXMLFile {

public static byte[] decompress(byte[] data) throws IOException, DataFormatException {
Inflater inflater = new Inflater();
inflater.setInput(data);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[data.length*2];
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] output = outputStream.toByteArray();

return output;
}

public static void main(String args[]) {

try {

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

DefaultHandler handler = new DefaultHandler() {

boolean peaks = false;

public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {

if (qName.equalsIgnoreCase("PEAKS")) {
peaks = true;
}
}

public void endElement(String uri, String localName,
String qName) throws SAXException {
if (peaks) {peaks = false;}
}

public void characters(char ch[], int start, int length) throws SAXException {

if (peaks) {
String currentValue = new String(ch, start, length);
System.out.println(currentValue);
try {
byte[] array = decompress(DatatypeConverter.parseBase64Binary(currentValue));
System.out.println(array[1]);

} catch (IOException | DataFormatException e) {e.printStackTrace();}
peaks = false;
}
}
};

saxParser.parse("file1_zlib.mzxml", handler);

} catch (Exception e) {e.printStackTrace();}
}

}

有没有更安全的方法来读取大型 xml 文件?你能告诉我错误是从哪里来的或者如何避免吗?

谢谢,迈克尔

最佳答案

The procedure characters(ch,start,length) does not read the complete entry in the line shown before. The length-value seems to be to small.

这正是它设计的工作方式。来自documentation of ContentHandler :

SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks.

因此,您不应尝试在characters 实现中调用decompress。相反,你应该将你得到的字符追加到一个可扩展的缓冲区中,并且只有在你得到相应的 endElement 时才调用 decompress:

StringBuilder sb = null;

public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("PEAKS")) {
sb = new StringBuilder();
}
}

public void endElement(String uri, String localName, String qName) throws SAXException {
if (sb == null) return;
try {
byte[] array = decompress(DatatypeConverter.parseBase64Binary(sb.toString()));
System.out.println(array[1]);
} catch (IOException | DataFormatException e) {e.printStackTrace();}
sb = null;
}

public void characters(char ch[], int start, int length) throws SAXException {
if (sb == null) return;
String currentValue = new String(ch, start, length);
sb.appens(currentValue);
}

关于java - 使用 SAX : value cut in 2 halves 在 Java 中解析 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19790091/

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