如何在java中提高StAX xml解析器的速度?

如何在java中提高StAX xml解析器的速度?,java,xml,stax,Java,Xml,Stax,我有一个使用StAX的XML解析器,我正在使用它来解析一个巨大的文件。然而,我想把时间尽可能地缩短。我正在读取将其放入数组中的值,并将其发送给另一个函数进行计算。我正在调用displayName标记,它应该在获取名称后立即转到下一个xml,而不是读取整个xml文件。我正在寻找最快的方法 Java: import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.

我有一个使用
StAX
的XML解析器,我正在使用它来解析一个巨大的文件。然而,我想把时间尽可能地缩短。我正在读取将其放入数组中的值,并将其发送给另一个函数进行计算。我正在调用
displayName
标记,它应该在获取名称后立即转到下一个xml,而不是读取整个xml文件。我正在寻找最快的方法

Java:


import java.io.File;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.*;

public class Driver {

    private static boolean bname;

    public static void main(String[] args) throws FileNotFoundException, XMLStreamException {

        File file = new File("C:\\Users\\Robert\\Desktop\\root\\SDKCode\\src\\main\\java\\com\\example\\xmlClass\\data.xml");


        parser(file);
    }

    public static void parser(File file) throws FileNotFoundException, XMLStreamException {

        bname = false;


        XMLInputFactory factory = XMLInputFactory.newInstance();


        XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(file));


        while (eventReader.hasNext()) {

            XMLEvent event = eventReader.nextEvent();

            // This will trigger when the tag is of type <...>
            if (event.isStartElement()) {
                StartElement element = (StartElement) event;


                Iterator<Attribute> iterator = element.getAttributes();
                while (iterator.hasNext()) {
                    Attribute attribute = iterator.next();
                    QName name = attribute.getName();
                    String value = attribute.getValue();
                    System.out.println(name + " = " + value);
                }


                if (element.getName().toString().equalsIgnoreCase("displayName")) {
                    bname = true;
                }

            }


            if (event.isEndElement()) {
                EndElement element = (EndElement) event;


                if (element.getName().toString().equalsIgnoreCase("displayName")) {
                    bname = false;
                }


            }


            if (event.isCharacters()) {
                // Depending upon the tag opened the data is retrieved .
                Characters element = (Characters) event;

                if (bname) {
                    System.out.println(element.getData());
                }

            }
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<results
        xmlns="urn:www-collation-com:1.0"
        xmlns:coll="urn:www-collation-com:1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:www-collation-com:1.0
              urn:www-collation-com:1.0/results.xsd">

    <WebServiceImpl array="1"
        guid="FFVVRJ5618KJRHNFUIRV845NRUVHR" xsi:type="coll:com.model.topology.app.web.WebService">
        <isPlaceholder>false</isPlaceholder>
        <displayName>server.servername1.siqom.siqom.us.com</displayName>
        <hierarchyType>WebService</hierarchyType>
        <hierarchyDomain>app.web</hierarchyDomain>
    </WebServiceImpl>
</results>

<?xml version="1.0" encoding="UTF-8"?>
<results
        xmlns="urn:www-collation-com:1.0"
        xmlns:coll="urn:www-collation-com:1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:www-collation-com:1.0
              urn:www-collation-com:1.0/results.xsd">

    <WebServiceImpl array="1"
        guid="FFVVRJ5618KJRHNFUIRV845NRUVHR" xsi:type="coll:com.model.topology.app.web.WebService">
        <isPlaceholder>false</isPlaceholder>
        <displayName>server.servername2.siqom.siqom.us.com</displayName>
        <hierarchyType>WebService</hierarchyType>
        <hierarchyDomain>app.web</hierarchyDomain>
    </WebServiceImpl>
</results>

<?xml version="1.0" encoding="UTF-8"?>
<results
        xmlns="urn:www-collation-com:1.0"
        xmlns:coll="urn:www-collation-com:1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:www-collation-com:1.0
              urn:www-collation-com:1.0/results.xsd">

    <WebServiceImpl array="1"
        guid="FFVVRJ5618KJRHNFUIRV845NRUVHR" xsi:type="coll:com.model.topology.app.web.WebService">
        <isPlaceholder>false</isPlaceholder>
        <displayName>server.servername3.siqom.siqom.us.com</displayName>
        <hierarchyType>WebService</hierarchyType>
        <hierarchyDomain>app.web</hierarchyDomain>
    </WebServiceImpl>
</results>


etc...


导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileReader;
导入java.util.Iterator;
导入javax.xml.namespace.QName;
导入javax.xml.stream.XMLEventReader;
导入javax.xml.stream.XMLInputFactory;
导入javax.xml.stream.XMLStreamException;
导入javax.xml.stream.events.*;
公务舱司机{
私有静态布尔bname;
公共静态void main(字符串[]args)抛出FileNotFoundException、XMLStreamException{
File File=新文件(“C:\\Users\\Robert\\Desktop\\root\\SDKCode\\src\\main\\java\\com\\example\\xmlClass\\data.xml”);
解析器(文件);
}
公共静态void解析器(文件)抛出FileNotFoundException、XMLStreamException{
bname=false;
XMLInputFactory=XMLInputFactory.newInstance();
XMLEventReader eventReader=factory.createXMLEventReader(新文件读取器(文件));
while(eventReader.hasNext()){
XMLEvent=eventReader.nextEvent();
//这将在标记类型为时触发
if(event.isStartElement()){
StartElement=(StartElement)事件;
迭代器迭代器=element.getAttributes();
while(iterator.hasNext()){
Attribute=iterator.next();
QName name=attribute.getName();
字符串值=attribute.getValue();
System.out.println(名称+“=”+值);
}
if(element.getName().toString().equalsIgnoreCase(“displayName”)){
bname=true;
}
}
if(event.isEndElement()){
EndElement元素=(EndElement)事件;
if(element.getName().toString().equalsIgnoreCase(“displayName”)){
bname=false;
}
}
if(event.isCharacters()){
//根据打开的标签检索数据。
Characters元素=(Characters)事件;
如果(bname){
System.out.println(element.getData());
}
}
}
}
}
XML:


import java.io.File;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.*;

public class Driver {

    private static boolean bname;

    public static void main(String[] args) throws FileNotFoundException, XMLStreamException {

        File file = new File("C:\\Users\\Robert\\Desktop\\root\\SDKCode\\src\\main\\java\\com\\example\\xmlClass\\data.xml");


        parser(file);
    }

    public static void parser(File file) throws FileNotFoundException, XMLStreamException {

        bname = false;


        XMLInputFactory factory = XMLInputFactory.newInstance();


        XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(file));


        while (eventReader.hasNext()) {

            XMLEvent event = eventReader.nextEvent();

            // This will trigger when the tag is of type <...>
            if (event.isStartElement()) {
                StartElement element = (StartElement) event;


                Iterator<Attribute> iterator = element.getAttributes();
                while (iterator.hasNext()) {
                    Attribute attribute = iterator.next();
                    QName name = attribute.getName();
                    String value = attribute.getValue();
                    System.out.println(name + " = " + value);
                }


                if (element.getName().toString().equalsIgnoreCase("displayName")) {
                    bname = true;
                }

            }


            if (event.isEndElement()) {
                EndElement element = (EndElement) event;


                if (element.getName().toString().equalsIgnoreCase("displayName")) {
                    bname = false;
                }


            }


            if (event.isCharacters()) {
                // Depending upon the tag opened the data is retrieved .
                Characters element = (Characters) event;

                if (bname) {
                    System.out.println(element.getData());
                }

            }
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<results
        xmlns="urn:www-collation-com:1.0"
        xmlns:coll="urn:www-collation-com:1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:www-collation-com:1.0
              urn:www-collation-com:1.0/results.xsd">

    <WebServiceImpl array="1"
        guid="FFVVRJ5618KJRHNFUIRV845NRUVHR" xsi:type="coll:com.model.topology.app.web.WebService">
        <isPlaceholder>false</isPlaceholder>
        <displayName>server.servername1.siqom.siqom.us.com</displayName>
        <hierarchyType>WebService</hierarchyType>
        <hierarchyDomain>app.web</hierarchyDomain>
    </WebServiceImpl>
</results>

<?xml version="1.0" encoding="UTF-8"?>
<results
        xmlns="urn:www-collation-com:1.0"
        xmlns:coll="urn:www-collation-com:1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:www-collation-com:1.0
              urn:www-collation-com:1.0/results.xsd">

    <WebServiceImpl array="1"
        guid="FFVVRJ5618KJRHNFUIRV845NRUVHR" xsi:type="coll:com.model.topology.app.web.WebService">
        <isPlaceholder>false</isPlaceholder>
        <displayName>server.servername2.siqom.siqom.us.com</displayName>
        <hierarchyType>WebService</hierarchyType>
        <hierarchyDomain>app.web</hierarchyDomain>
    </WebServiceImpl>
</results>

<?xml version="1.0" encoding="UTF-8"?>
<results
        xmlns="urn:www-collation-com:1.0"
        xmlns:coll="urn:www-collation-com:1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:www-collation-com:1.0
              urn:www-collation-com:1.0/results.xsd">

    <WebServiceImpl array="1"
        guid="FFVVRJ5618KJRHNFUIRV845NRUVHR" xsi:type="coll:com.model.topology.app.web.WebService">
        <isPlaceholder>false</isPlaceholder>
        <displayName>server.servername3.siqom.siqom.us.com</displayName>
        <hierarchyType>WebService</hierarchyType>
        <hierarchyDomain>app.web</hierarchyDomain>
    </WebServiceImpl>
</results>


etc...


错误的
server.servername1.siqom.siqom.us.com
网络服务
app.web
错误的
server.servername2.siqom.siqom.us.com
网络服务
app.web
错误的
server.servername3.siqom.siqom.us.com
网络服务
app.web
等

由于我可以看到多个xml文件进行解析,您可以使用多线程一次解析3个xml文件,并将对象存储在线程安全列表(如CopyOnWriteArrayList)或线程安全映射(如并发哈希映射)中。如果您正在使用Stax解析器进行解析,那么它已经过优化,可以用于更大的xml文件。此外,如果不需要XMl中的所有数据,可以使用XPath,XPath和流式XMl解析也是不同的。

因为我可以看到多个XMl文件进行解析,您可以使用多线程一次解析3个xml文件,并将对象存储在线程安全列表(如CopyOnWriteArrayList)或线程安全映射(如并发哈希映射)中。如果您正在使用Stax解析器进行解析,那么它已经过优化,可以用于更大的xml文件。此外,如果不需要XMl中的所有数据,可以使用XPath,XPath和流式XMl解析也是不同的

拆分文件 首先,如果您的大文件实际上是几个串联的XML文件(如您所示的示例),那么这个大文件不是(有效的)XML文件,我建议在处理到严格的XML解析库(Stax、DOM、SAX、XSL等等)之前将其拆分

一个有效的XML文件只有一个prolog和一个根元素

您可以使用纯IO/字节级API(不涉及XML),将XML prolog用作分割标记

然后,可以将每个拆分视为单个XML“文件”(如果需要,可以独立处理,用于多线程目的)。我不是随便说“文件”,它可能是从原来的“大文件”中分离出来的
byte[]

加速XML解析 关于你的代码 使用
XMLEventReader
,您的示例代码中有一些突出的地方

  • 您不应该像这样迭代一个属性。除非我遗漏了什么,否则您不会在这个迭代中做任何事情
  • 一旦您到达
    START\u元素
    ,它的
    localName
    displayName
    ,您就应该调用它,它是解析器的内部,有一些优化技巧来提高速度,而while循环无法实现。此调用将使读取器保留在匹配的
    END\u元素
    ,因此实际上,您简化了代码(仅检查
    displayName
    START\u元素
    ,仅此而已)
  • 您的XML似乎格式良好,因此您可以在找到结果后立即跳过解析
  • xmlinputfactures
    是要重用的,所以不要为每个文件创建一个,而是创建一个共享实例
  • XML(xxx)阅读器
    是可关闭的,所以请关闭它们
  • 一些XML库具有JDK提供的更快的字符解码方案(了解XML编码的内部使他们能够做到这一点),因此如果您有有效的XML prolog,请在fil的开头标记编码