Java xml文件的部分读取
我需要从大约100个XML文件中读取前15行,这些XML文件长达200000行。有没有一种方法可以有效地使用类似的工具?使用中概述的步骤;这将尝试一次解析整个文件Java xml文件的部分读取,java,xml,parsing,file-io,gosu,Java,Xml,Parsing,File Io,Gosu,我需要从大约100个XML文件中读取前15行,这些XML文件长达200000行。有没有一种方法可以有效地使用类似的工具?使用中概述的步骤;这将尝试一次解析整个文件 编辑:前15个元素包含有关文件的元数据(页面名称、上次编辑日期等),我想将其解析到一个表中。这里有一个简单的解决方案,它将逐行读取文件,直到它在lines变量中存储15行数据(如果文件较小,则小于15行) 您最好像下面这样手动阅读。在您的情况下,DOM解析器将非常昂贵。如果确实想解析xml并提取/插入节点,可以使用SAX解析器 try
编辑:前15个元素包含有关文件的元数据(页面名称、上次编辑日期等),我想将其解析到一个表中。这里有一个简单的解决方案,它将逐行读取文件,直到它在lines变量中存储15行数据(如果文件较小,则小于15行)
您最好像下面这样手动阅读。在您的情况下,DOM解析器将非常昂贵。如果确实想解析xml并提取/插入节点,可以使用SAX解析器
try (BufferedReader br = new BufferedReader(new FileReader("C:\\testing.txt")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
}
我建议研究流式XML解析器;流式API的用例扩展到读取数个100 GB的文件,这些文件显然无法放入内存 在Java中,API是本机SAXAPI的(相当大的)演变。查看此处有关“动态”解析的教程:
这里可能是您想要做的事情——正如我在评论中所写的,使用SAX解析器,当您的停止条件满足时,使用这个解析器 编辑: test.xml 输出 为什么这样更好?只是因为某些应用程序可以向您发送
<?xml version="1.0" encoding="UTF-8"?>
<root>
<first><inner>data</inner></first>
<second>second</second>
<third>third</third>
<next>next</next>
</root>
数据
第二
第三
下一个
而面向行的方法将失败
我提供了一个不计算元素的解析器,以表明可以根据实现以下目标所需的业务逻辑来定义条件
字符()警告
要读取元素中的数据,可以使用character()
方法,但请注意
SAX解析器可以返回单个块中的所有连续字符数据,也可以将其拆分为多个块
在中阅读更多内容假设您想阅读以下内容:
<?xml ...?>
<root>
<element>data</element>
...
<otherElement>more data</otherElement>
<ignoredElement> ... </ignoredElement>
... more ignored Elements
</root>
然后您需要创建一个ContentHandler
类作为您的数据处理程序。我将其称为DataSaxHandler
。如果扩展DefaultHandler
,只需实现感兴趣的方法。这是一个可以作为起点的示例。它将检测每个元素的开始和结束,并将其打印出来。它将统计15个结束标记(它不会生成格式良好的输出),并将忽略属性。使用它作为起点(我没有测试它):
DocumentBuilder(DOM)尝试解析所有内容。如果您想读取行,实际上应该使用
BufferedReader
。如果您想读取标记,那么应该使用SAX(org.xml.SAX)读取器(或xml读取器),它将允许您按顺序读取xml并响应由找到的标记引起的事件。一旦有了xml,请尝试将其作为xml读取。我不确定这是否可行,但我建议将SAX解析器()修改为在读取前15个元素时结束,但请注意,即使长XML也可以仅在一行中…您可以计算在startElement
方法中读取的元素数,并在读取一定数量(元素数,而不是行数)时停止我希望利用解析器带来的xml友好方法。如果只使用BufferedReader,我不需要手动分离元素吗?您可能可以使用SAX解析器,并在characters()
方法中计算换行。但是如果你真的想从文件的开头提取一些东西,你可以在找到它的时候停止,这取决于OP打算对前15行做什么。如果他们想解析XML,他们应该使用流式解析器,即SAX,它不像DOM解析器那样加载整个文档。对代码进行简单解释,然后我可能会+1它。|=^]对我来说,这看起来很自我描述,但对每个人来说都不一样。这是allIt最好在这里粘贴一些代码,因为这个问题有一些不同的上下文。我认为这是非常相同和直接的,但我提供了代码;-)您还可以在上面的评论中添加链接以供将来参考吗?评论在一段时间后不可编辑,但在将来,人们会参考经过投票和接受的答案,以便找到自己的答案;-)
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 ReadXmlUpToSomeElementSaxParser extends DefaultHandler {
private final String lastElementToRead;
public ReadXmlUpToSomeElementSaxParser(String lastElementToRead) {
this.lastElementToRead = lastElementToRead;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// just for showing what is parsed
System.out.println("startElement: " + qName);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (lastElementToRead.equals(qName)) {
throw new MySaxTerminatorException();
}
}
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
try {
saxParser.parse("src/test.xml", new ReadXmlUpToSomeElementSaxParser("second"));
} catch (MySaxTerminatorException exp) {
// nothing to do, expected
}
}
public class MySaxTerminatorException extends SAXException {
}
}
startElement: root
startElement: first
startElement: inner
startElement: second
<?xml version="1.0" encoding="UTF-8"?>
<root>
<first><inner>data</inner></first>
<second>second</second>
<third>third</third>
<next>next</next>
</root>
<?xml ...?>
<root>
<element>data</element>
...
<otherElement>more data</otherElement>
<ignoredElement> ... </ignoredElement>
... more ignored Elements
</root>
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader reader = sp.getXMLReader();
public class DataSaxHandler extends DefaultHandler {
private int countTags = 0;
private boolean inElement = false;
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
System.out.println("<" + qName + ">");
inElement = true;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
countTags++;
System.out.println("</" + qName + ">");
inElement = false;
if(countTags > 15) {
// throw some exception to stop parsing
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(inElement) {
System.out.println(new String(ch, start, length));
}
}
}
reader.setContentHandler(new DataSaxHandler());
reader.parse(new InputSource(new FileInputStream(new File(PATH, "data.xml"))));