XML解析

XmlToObject


package com.zx.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

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

import net.sourceforge.wurfl.core.resource.ModelDevice;

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

import com.zx.dao.WurflDao;

public class XmlToObject {

    
    private String filePath="wurfl.xml";
    
    
    
    public void  parseXml()
    {
        
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser;
        ClassLoader  loader=XmlToObject.class.getClassLoader();
        URL url =loader.getResource(filePath);
        try {
            parser = factory.newSAXParser();
            InputStream in = new FileInputStream(new File(url.getFile()));
            parser.parse(in, new MySAXHandler());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
    }

    
    public static void main(String[] args)
    {
        XmlToObject xmlToObject=new XmlToObject();
        xmlToObject.parseXml();
    }
}


class MySAXHandler extends DefaultHandler
{

    static int count=0;
    
//    ModelDevicePojo currentDevice=null;
    ModelDevice currentDevice=null;
    String userAgent;
    String id;
    String fallBack;
    boolean specific;
    boolean actualDeviceRoot;
    
    Map<String,String> capabilities=null;
    Map<String,String> groupsByCapability=null;
    String groupsid;
    String capabilityName;
    String capabilityValue;
        
    
    long start=0;
    long end=0;
    
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
    }

    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        System.out.println("==wurfl.xml==");
        end=System.currentTimeMillis();
        
//        System.out.println("device:"+deviceList.size());
//        System.out.println("first device groups:"+deviceList.get(0).getGroups().size());
//        System.out.println("first device first group capabilitys:"+deviceList.get(0).getGroups().get(0).getCapabilitys().size());
        //WurflDao.set(deviceList.subList(0,100));
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        // TODO Auto-generated method stub
        
        if(name.equals("device"))
        {
            
//            currentDevice=new ModelDevice(userAgent, id, fallBack,
//                    actualDeviceRoot, capabilities, groupsByCapability);
            currentDevice = new ModelDevice.Builder(id, userAgent,
                        fallBack).setActualDeviceRoot(actualDeviceRoot).setSpecific(specific)
                        .setCapabilities(capabilities).setCapabilitiesByGroup(
                                groupsByCapability).build();
            
            System.out.println("-------------------"+(++count)+"---------------");
                WurflDao.set(currentDevice);
            
            capabilities=null;
            groupsByCapability=null;
            currentDevice=null;
            
        }else if(name.equals("group"))
        {
            
        }else if(name.equals("capability"))
        {
            groupsByCapability.put(capabilityName, groupsid);
            capabilities.put(capabilityName, capabilityValue);
        }
        
        
    }

    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        
        System.out.println("==");
        start=System.currentTimeMillis();
    }

    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        System.out.println(name);
        int len=attributes.getLength();
        if(name.equals("device"))
        {
            if(groupsByCapability==null)
            {
                groupsByCapability=new HashMap<String,String>();
            }
            if(capabilities==null)
            {
                capabilities=new HashMap<String,String>();
            }
            for(int i=0;i<len;i++)
            {
                String attrName=attributes.getQName(i);
                String attrValue=attributes.getValue(i);
                
//                System.out.println(attrName+":"+attrValue);
                if(attrName.equals("id"))
                {
                    this.id=attrValue;
                }else if(attrName.equals("user_agent"))
                {
                    if(attrValue==null)
                    {
                        this.userAgent="";
                    }else
                    {
                        this.userAgent=attrValue;
                    }
                    
                }else if(attrName.equals("fall_back"))
                {
                    this.fallBack=attrValue;
                }else if(attrName.equals("actual_device_root"))
                {
                    if(attrValue.equals("true"))
                    {
                        this.actualDeviceRoot=true;
                    }else
                    {
                        this.actualDeviceRoot=false;
                    }
                }else if(attrName.equals("specific"))
                {
//                    this.specific=specific;
                    if(attrValue.equals("true"))
                    {
                        this.specific=true;
                    }else
                    {
                        this.specific=false;
                    }
                }
                
                
            }
            
        }else if(name.equals("group"))
        {
            
            
            for(int i=0;i<len;i++)
            {
                String attrName=attributes.getQName(i);
                String attrValue=attributes.getValue(i);
                
                if(attrName.equals("id"))
                {
                    this.groupsid=attrValue;
                }
                
                
            }
            
            
        }else if(name.equals("capability"))
        {
            
            for(int i=0;i<len;i++)
            {
                String attrName=attributes.getQName(i);
                String attrValue=attributes.getValue(i);
                
                if(attrName.equals("name"))
                {
                    capabilityName=attrValue;
                }else if(attrName.equals("value"))
                {
                    capabilityValue=attrValue;
                }
            }
        }
    }
}






XMLResource



/**
 * Copyright (c) 2011 ScientiaMobile Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Refer to the COPYING file distributed with this package.
 */
package net.sourceforge.wurfl.core.resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.text.StrBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;

/**
 * XMLResource
 * <p/>
 * <p>
 * XMLResource represent a source of wurfl repository backed by XML file. XML
 * file can be root file or patch. The XML file can be compresses by gzip or
 * zip. In case of zip, the first entry will be processed.
 * </p>
 * <p/>
 * <p>
 * The given path can be URL or filesystem path. The URL support classpath
 * scheme to load file from java classpath.
 * </p>
 *
 * @author Fantayeneh Asres Gizaw
 * @author Filippo De Luca
 * @version $Id: XMLResource.java 668 2011-06-14 07:07:44Z ermanno.franco $
 */
public class XMLResource implements WURFLResource {

    private static final Logger logger = LoggerFactory.getLogger(XMLResource.class);

    private URI uri;

    private InputStream stream;

    /**
     * Build Resource by path. The path can be URI or filesystem path.
     *
     * @param path The path of source file.
     */
    public XMLResource(String path) {

        Validate.notEmpty(path, "The path must be not empty");

        try {
            uri = createURI(path);
        } catch (URISyntaxException e) {
            throw new WURFLResourceException(this, e);
        }

    }

    /**
     * Build resource by File.
     *
     * @param file The source File
     */
    public XMLResource(File file) {

        Validate.notNull(file, "The file must be not null");

        uri = file.toURI();
    }

    /**
     * Build resource by URI. It handle the 'classpath' schema also.
     *
     * @param uri The source URI
     */
    public XMLResource(URI uri) {

        Validate.notNull(uri, "The URI must be not null");

        this.uri = uri;
    }

    /**
     * Build resource by InputStream. The builded resource can be reloadable
     * only if the given stream is resettable (the maskSupported method returns
     * true).
     *
     * @param stream The source stream.
     */
    public XMLResource(InputStream stream) {

        Validate.notNull(stream, "The stream must be not null");

        this.stream = stream;
    }

    // Access methods *****************************************************

    /**
     * {@inheritDoc}
     */
    public ResourceData getData() {

        if (stream == null) {
            if (uri != null) {
                stream = openInputStream(uri);
            } else {
                throw new WURFLResourceException(this,
                        "The resource can not be read, the stream is null");
            }
        }

        ResourceData data = readData(stream);

        if (stream.markSupported()) {
            try {
                stream.reset();
            } catch (IOException e) {
                releaseStream();
            }
        } else {
            releaseStream();
        }

        return data;
    }

    /**
     * {@inheritDoc}
     * <p/>
     * If this resource is created using InputStream, the info will return
     * Stream resource'.
     */
    public String getInfo() {

        String info = null;

        if (uri != null) {
            info = uri.toString();
        } else {
            info = "Stream resource";
        }

        return info;
    }

    /**
     * {@inheritDoc}
     */
    public void release() {
        if (stream != null) {
            releaseStream();
        }

        uri = null;
    }

    /**
     * Return if this resource can be reloaded.
     *
     * @return true if can be reloaded, false otherwise.
     */
    public boolean isReloadable() {

        boolean isStreamResettable = stream != null && stream.markSupported();

        return isStreamResettable || uri != null;
    }

    // Helper methods *****************************************************

    /**
     * Creates a URI from the given String. If the path can be an URI
     * representation or a filesystem path. It handle the Windows path also.
     */
    public static URI createURI(String path) throws URISyntaxException {
        assert StringUtils.isNotBlank(path) : "The path must be not blank";
        URI createdURI = null;
        if (logger.isDebugEnabled()) {
            logger.debug("looking for a local file: " + path);
        }
        File f = new File(path);
        if (f.exists() && f.isFile() && f.canRead()) {
            createdURI = f.toURI();
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug(path + " not found in local filesystem, looking for other");
            }
            StrBuilder workingPathBuilder = new StrBuilder(path);
            workingPathBuilder.replaceAll(" ", "%20");
            // FIXME where the path must be normalized?
            if (SystemUtils.IS_OS_WINDOWS && StringUtils.contains(path, "\\")) {
                logger.debug("Encoding windows URI");
                workingPathBuilder.replaceAll("\\\\", "/");
            }
            // The path doesn't represent an URI yet, perhaps a Intranet resource?
            if (!workingPathBuilder.contains(':')) {
                while (workingPathBuilder.startsWith("/")) {
                    workingPathBuilder = workingPathBuilder.deleteCharAt(0);
                }
                workingPathBuilder.insert(0, "file:///");
            }
            // Assumes the path is an URI
            createdURI = URI.create(workingPathBuilder.toString());
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Created URI: " + createdURI + " from path: " + path);
        }
        return createdURI;
    }

    /**
     * Convert spaces to &quot;%20&quot;
     *
     * @param location Location to convert.
     * @return converted location.
     * @deprecated use {@link XMLResource#createURI(String)}
     */
    public static URI toURI(String location) throws URISyntaxException {
        return new URI(StringUtils.replace(location, " ", "%20"));
    }

    /**
     * Opens the InputStream by giving URI. The given URI support the
     * 'classpath' schema also.
     *
     * @param uri The given URI
     * @return The InputStream opened from the given URI
     */
    protected InputStream openInputStream(URI uri) {

        InputStream input = null;

        try {

            URI resourceURI = resourceURI(uri);
            URLConnection connection = resourceURI.toURL().openConnection();

            if (resourceURI.getPath().endsWith(".zip")) {
                input = fromZipFile(connection.getInputStream());
            } else if (resourceURI.getPath().endsWith(".gz")) {
                input = new GZIPInputStream(connection.getInputStream());
            } else {
                input = connection.getInputStream();
            }
        } catch (IOException e) {
            logger.error("Error opening stream URI:" + uri.toString());
            throw new WURFLResourceException(this, e);
        }

        logger.debug("Opened stream from URI: " + uri);

        return input;
    }

    private InputStream fromZipFile(InputStream inputStream) throws IOException {
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        zipInputStream.getNextEntry();
        return zipInputStream;
    }

    private URI resourceURI(final URI uri) throws MalformedURLException {
        if (uri.getScheme().equals("classpath")) {
            StrBuilder pathBuilder = new StrBuilder();
            pathBuilder.append(uri.toString());
            pathBuilder.replaceFirst("classpath:", "");
            return URI.create(getClass().getResource(pathBuilder.toString())
                    .toString());
        }

        return uri;
    }

    /**
     * Read the ResourceData from given stream.
     *
     * @param input The stream to read data from.
     * @return Read ResourceData.
     */
    protected ResourceData readData(InputStream input) {

        WURFLSAXHandler handler = new WURFLSAXHandler();  

        try {
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            parser.parse(input, handler);
        } catch (Exception e) {
            throw new WURFLResourceException(this, e);
        }

        String name = getInfo();
        String version = handler.getVer();
        boolean patch = handler.isPatch();
        ModelDevices devices = handler.getDevices();

        ResourceData data = new ResourceData(name, version, patch, devices);

        logger.debug("Readed data: " + data);

        return data;
    }

    private void releaseStream() {
        try {
            stream.close();
        } catch (IOException e) {
            logger.warn("Error closing stream");
        }

        stream = null;
    }

    // Helper classes *****************************************************

    static class WURFLSAXHandler extends DefaultHandler {

        // XML costants ***************************************************

        private static final String ELEM_WURFL = "wurfl";
        private static final String ELEM_WURFL_PATCH = "wurfl_patch";
        private static final String ELEM_DEVICE = "device";
        private static final String ELEM_GROUP = "group";
        private static final String ELEM_CAPABILITY = "capability";
        private static final String ELEM_VER = "ver";

        private static final String ATTR_DEVICE_ID = "id";
        private static final String ATTR_DEVICE_FALLBACK = "fall_back";
        private static final String ATTR_DEVICE_USERAGENT = "user_agent";
        private static final String ATTR_DEVICE_ACTUALDEVICEROOT = "actual_device_root";
        private static final String ATTR_DEVICE_SPECIFIC = "specific";


        private static final String ATTR_GROUP_ID = "id";

        private static final String ATTR_CAPABILITY_NAME = "name";
        private static final String ATTR_CAPABILITY_VALUE = "value";

        // Memebers *******************************************************

        private String userAgent;

        private String deviceID;

        private String fallBack;

        private boolean actualDeviceRoot;

        private boolean specific;

        private String groupID;

        private String capabilityName;

        private String capabilityValue;

        private Set userAgents;

        private Set devicesId;

        private Map capabilities;

        private Map capabilitiesByGroup;

        private ModelDevices devices;

        private final Map/*String, ModelDevice*/ rootDevices = new HashMap();

        private String ver;

        private boolean insideVer = false;

        private boolean patch = false;

        private boolean root = false;

        // Access methods *************************************************

        public String getVer() {
            return ver;
        }

        public ModelDevices getDevices() {
            return devices;
        }

        public Set getRootDevices() {
            return new HashSet(rootDevices.values());
        }

        public boolean isPatch() {
            return patch;
        }

        // Parser methods *************************************************

        public void startDocument() throws SAXException {
            super.startDocument();
            userAgents = new HashSet();
            devicesId = new HashSet();
            devices = new ModelDevices();
        }

        public void endDocument() throws SAXException {
        }

        public void startElement(String uri, String localName, String name,
                                 Attributes attributes) throws SAXException {
            if (ELEM_DEVICE.equals(name)) {
                deviceStartElement(attributes);
            } else if (ELEM_GROUP.equals(name)) {
                startGroupElement(attributes);
            } else if (ELEM_CAPABILITY.equals(name)) {
                startCapabilityElement(attributes);
            } else if (ELEM_VER.equals(name)) {
                startVerElement();
            } else if (ELEM_WURFL_PATCH.equals(name)) {
                startWurflPatchElement();
            } else if (ELEM_WURFL.equals(name)) {
                startWurflElement();
            }
        }

        public void endElement(String uri, String localName, String name)
                throws SAXException {
            if (ELEM_GROUP.equals(name)) {
                endGroupElement();
            } else if (ELEM_DEVICE.equals(name)) {
                endDeviceElement();
            } else if (ELEM_VER.equals(name)) {
                endVerElement();
            }
        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
            if (insideVer) {
                charsVer(ch, start, length);
            }
        }

        private void startWurflElement() {

            if (patch || root) {
                throw new WURFLParsingException(
                        "Root element already defined: wurfl");
            }

            root = true;

        }

        private void startWurflPatchElement() {
            if (patch || root) {
                throw new WURFLParsingException(
                        "Root element already defined: wurfl_patch");
            }

            patch = true;
        }

        private void startVerElement() {
            insideVer = true;
        }

        public void charsVer(char[] ch, int start, int length) {
            StrBuilder verBuilder = new StrBuilder();
            verBuilder.append(ch, start, length);

            ver = verBuilder.toString();
        }

        private void endVerElement() {
            insideVer = false;
        }

        private void deviceStartElement(Attributes attributes) {

            userAgent = attributes.getValue(ATTR_DEVICE_USERAGENT);
            deviceID = attributes.getValue(ATTR_DEVICE_ID);
            fallBack = attributes.getValue(ATTR_DEVICE_FALLBACK);
            actualDeviceRoot = Boolean.valueOf(
                    attributes.getValue(ATTR_DEVICE_ACTUALDEVICEROOT))
                    .booleanValue();

            specific = Boolean.valueOf(attributes.getValue(ATTR_DEVICE_SPECIFIC))
                    .booleanValue();
            // check if the user agent and device id are valid values
            if (StringUtils.isEmpty(deviceID)) {
                throw new WURFLParsingException("device id is not a valid");
            }
            if (!"generic".equals(deviceID) && StringUtils.isEmpty(userAgent)) {
                StringBuffer msg = new StringBuffer();
                msg.append("Device with id ").append(deviceID).append(
                        " has an invalid user agent");
                throw new WURFLParsingException(msg.toString());
            }

            // check if the device id and the user_agent are unique
            if (devicesId.contains(deviceID)) {
                throw new WURFLParsingException("device id " + deviceID
                        + " already defined!!!");
            }

            if (userAgents.contains(userAgent)) {
                throw new WURFLParsingException("user agent [" + userAgent
                        + "] already defined");
            }

            userAgents.add(userAgent);
            devicesId.add(deviceID);

            capabilities = new HashMap();
            capabilitiesByGroup = new HashMap();
        }

        private void endDeviceElement() {

            ModelDevice device = new ModelDevice.Builder(deviceID, userAgent,
                    fallBack).setActualDeviceRoot(actualDeviceRoot).setSpecific(specific)
                    .setCapabilities(capabilities).setCapabilitiesByGroup(
                            capabilitiesByGroup).build();

            devices.add(device);

            if (device.isActualDeviceRoot()) rootDevices.put(deviceID, device);
        }

        private void startCapabilityElement(Attributes attributes) {

            capabilityName = attributes.getValue(ATTR_CAPABILITY_NAME);
            capabilityValue = attributes.getValue(ATTR_CAPABILITY_VALUE);

            if (StringUtils.isEmpty(capabilityName) || null == capabilityValue) {
                throw new WURFLParsingException("device with id " + deviceID
                        + " has capability with name or value not valid");
            }

            if (capabilities.containsKey(capabilityName)) {
                throw new WURFLParsingException("The devices with id "
                        + deviceID + " define more " + capabilityName);
            }

            // intern by Kenny MacLeod
            String internCapabilityName = capabilityName.intern();
            String internGroupId = groupID.intern();

            capabilities.put(internCapabilityName, capabilityValue);
            capabilitiesByGroup.put(internCapabilityName, internGroupId);
        }

        private void startGroupElement(Attributes attributes) {

            groupID = attributes.getValue(ATTR_GROUP_ID);

        }

        private void endGroupElement() {
            /* Empty */
        }

    }

}



發佈了41 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章