当前位置: 首页 > 面试题库 >

最快,最优化的方式读取xml

马阳曦
2023-03-14
问题内容

我在XML文件下面有这个

<book>
<person>
  <first>Kiran</first>
  <last>Pai</last>
  <age>22</age>
</person>
<person>
  <first>Bill</first>
  <last>Gates</last>
  <age>46</age>
</person>
<person>
  <first>Steve</first>
  <last>Jobs</last>
  <age>40</age>
</person>
</book>

现在,下面显示了从XML文件读取数据的Java程序。

import java.io.File;
import org.w3c.dom.Document;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class ReadAndPrintXMLFile{

    public static void main (String argv []){
    try {

            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse (new File("book.xml"));

            // normalize text representation
            doc.getDocumentElement ().normalize ();
            System.out.println ("Root element of the doc is " + 
                 doc.getDocumentElement().getNodeName());


            NodeList listOfPersons = doc.getElementsByTagName("person");
            int totalPersons = listOfPersons.getLength();
            System.out.println("Total no of people : " + totalPersons);

            for(int s=0; s<listOfPersons.getLength() ; s++){


                Node firstPersonNode = listOfPersons.item(s);
                if(firstPersonNode.getNodeType() == Node.ELEMENT_NODE){


                    Element firstPersonElement = (Element)firstPersonNode;

                    //-------
                    NodeList firstNameList = firstPersonElement.getElementsByTagName("first");
                    Element firstNameElement = (Element)firstNameList.item(0);

                    NodeList textFNList = firstNameElement.getChildNodes();
                    System.out.println("First Name : " + 
                           ((Node)textFNList.item(0)).getNodeValue().trim());

                    //-------
                    NodeList lastNameList = firstPersonElement.getElementsByTagName("last");
                    Element lastNameElement = (Element)lastNameList.item(0);

                    NodeList textLNList = lastNameElement.getChildNodes();
                    System.out.println("Last Name : " + 
                           ((Node)textLNList.item(0)).getNodeValue().trim());

                    //----
                    NodeList ageList = firstPersonElement.getElementsByTagName("age");
                    Element ageElement = (Element)ageList.item(0);

                    NodeList textAgeList = ageElement.getChildNodes();
                    System.out.println("Age : " + 
                           ((Node)textAgeList.item(0)).getNodeValue().trim());

                    //------


                }//end of if clause


            }//end of for loop with s var


        }catch (SAXParseException err) {
        System.out.println ("** Parsing error" + ", line " 
             + err.getLineNumber () + ", uri " + err.getSystemId ());
        System.out.println(" " + err.getMessage ());

        }catch (SAXException e) {
        Exception x = e.getException ();
        ((x == null) ? e : x).printStackTrace ();

        }catch (Throwable t) {
        t.printStackTrace ();
        }
        //System.exit (0);

    }//end of main


}

结果是..

Root element of the doc is book
Total no of people : 3
First Name : Kiran
Last Name : Pai
Age : 22
First Name : Bill
Last Name : Gates
Age : 46
First Name : Steve
Last Name : Jobs
Age : 40

现在,我的查询是请告知是否还有其他最快的方式来读取此xml,我正在查看斋戒,请告知..!


问题答案:

如果性能对您而言很重要,则应首选SAX或StAX(http://en.wikipedia.org/wiki/StAX)而不是DOM。

使用时DOM,第一次将XML文件解析为对象模型,然后您可以提出要求。因此,对您而言,算法有两遍。

使用时SAX,在解析过程中,某些基于事件或推送模型的回调将被调用(startDocument,endElement...) 。SAX

使用StAX,您可以控制解析。您将光标从一个元素移动到另一个。这是拉模型。

对于包含32910000人的文件,我将我的版本与SAX的(Blaise Doughan的)过度回答进行了比较StAX。我删除了所有System.out.println指示。我的程序花了106秒读取所有文件,另一个花了94秒。我想这SAX是较慢的,因为callback即使它们都不执行任何操作都将被调用(push模型),而使用StAX时,光标仅在“ interresting”元素(pull模型)上移动。

例如,使用Java 7:

import java.io.File;

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 ReadAndPrintXMLFileWithSax {

    public static void main(String[] args) throws Exception {
        SAXParserFactory fabrique = SAXParserFactory.newInstance();
        SAXParser parser = fabrique.newSAXParser();

        File file = new File("book.xml");
        BookHandler handler = new BookHandler();
        parser.parse(file, handler);
    }

    public static class BookHandler extends DefaultHandler {
        private int count = 0;
        private StringBuilder buffer;

        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            switch (qName) {
            case "person":
                count++;
                break;
            case "first":
                buffer = new StringBuilder("First Name : ");
                break;
            case "last":
                buffer = new StringBuilder("Last Name : ");
                break;
            case "age":
                buffer = new StringBuilder("Age : ");
                break;
            }
        }

        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String content = new String(ch, start, length);
            if (buffer != null)
                buffer.append(content);
        }

        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            switch (qName) {
            case "first":
            case "last":
            case "age":
                System.out.println(buffer.toString());
                break;
            }
        }

        @Override
        public void endDocument() throws SAXException {
            System.out.println(count + " persons");
        }
    }
}


 类似资料:
  • 问题内容: 当给定一个MAX_BUFFER_SIZE的缓冲区以及一个远远超过该缓冲区的文件时,怎么办: 以MAX_BUFFER_SIZE的块读取文件? 尽快完成 我尝试使用NIO 和常规IO 事实证明, 常规IO在执行与NIO相同的操作时快约100倍 。我想念什么吗?这是预期的吗?有没有更快的方法来读取缓冲区块中的文件? 最终,我正在处理一个大文件,但我没有足够的内存来一次读取所有文件。相反,我想

  • 问题内容: 我想将值的符号表示为-1或1。 避免使用条件总是减少计算成本的好主意。例如,我可以想到的一种方法是使用快速获取符号: 或更简而言之: 这似乎是个好方法吗? 考虑到字节顺序问题(因为MSB保持签名),这将适用于所有平台吗? 问题答案: 您不简单使用的任何原因: 另外,大多数Number实现都有一个signum方法,该方法采用该类型的原语并返回一个int,因此可以避免强制转换以提高性能。

  •   梯度下降(GD)是最小化风险函数、损失函数的一种常用方法,随机梯度下降和批量梯度下降是两种迭代求解思路。 1 批量梯度下降算法   假设h(theta)是要拟合的函数,J(theta)是损失函数,这里theta是要迭代求解的值。这两个函数的公式如下,其中m是训练集的记录条数,j是参数的个数:   梯度下降法目的就是求出使损失函数最小时的theta。批量梯度下降的求解思路如下: 对损失函数求th

  • 问题内容: 我做了一个方法,需要一个和一个。它用该字符串作为内容的新文件替换该文件。 这就是我所做的: 但是,它非常缓慢。有时需要一分钟以上。 如何写出包含成千上万个字符的大文件? 问题答案: 确保分配了足够大的缓冲区: 您正在运行哪种操作系统?那也可以有很大的不同。但是,花一 分钟 时间写出一个小于大小的文件听起来像是系统问题。在Linux或其他* ix系统上,您可以使用类似的方法来查看JVM是

  • 问题内容: 从其他一些应用程序中,我正在获取XML文件。 我想逐个节点读取该XML文件,并将节点值存储在数据库中以备将来使用。 那么,使用Java读取XML文件和检索节点值的最佳方法/ API是什么? 问题答案: dom4j和jdom非常易于使用(暂时忽略“最佳”需求;))

  • 我正在制作一个视频流应用程序,使视频比特率适应可用的上行链路带宽,我希望它能动态地改变视频分辨率,这样就不会有太多的压缩工件在较低的比特率。虽然通过释放并调用上的和,然后为新的解析配置所有内容,我已经开始工作了,但这会导致流中非常明显的中断--在我的测试中至少中断半秒钟。 我使用OpenGL来缩放图像,当相机不支持所需的分辨率时,类似于这样。我用两个曲面初始化捕获会话--一个用于向用户预览(使用)