Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java xml文件的部分读取_Java_Xml_Parsing_File Io_Gosu - Fatal编程技术网

Java xml文件的部分读取

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

我需要从大约100个XML文件中读取前15行,这些XML文件长达200000行。有没有一种方法可以有效地使用类似的工具?使用中概述的步骤;这将尝试一次解析整个文件


编辑:前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"))));