XML读取和生成(总结)

来源:互联网 发布:java 四分位数 编辑:程序博客网 时间:2024/04/29 13:08

在Java应用开发里面,xml文件的读写相当重要和频繁,因此抱着将代码通用化的思路,遂成下文。第一次写原创,或多或少存在某些不足,希望能得到你的宝贵意见,以将代码更加通用化,更加健壮,更加能适应变化需求!

 

person.xml:

 

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<persons>
   <person id="1">
    <name>qjq</name>
    <age>20</age>
    <sex>male</sex>
 </person>
 <person id="2">
    <name>hqx</name>
    <age>19</age>
    <sex>female</sex>
   </person>
</persons>

 

 

Person.java

 

public class Person
{
    private int    id;
    private String name;
    private int    age;
    private String sex;

    public int getId()
    {
        return id;
    }
   
    public void setId(int id)
    {
        this.id = id;
    }
   
    public String getName()
    {
        return name;
    }
   
    public void setName(String name)
    {
        this.name = name;
    }
   
    public int getAge()
    {
        return age;
    }
   
    public void setAge(int age)
    {
        this.age = age;
    }
   
    public String getSex()
    {
        return sex;
    }
   
    public void setSex(String sex)
    {
        this.sex = sex;
    }
   
}

 

 

ParsePeron.java


package aa;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/////////////////  使用方法:直接Ctrl+F全部代替,用自己的类代替Person类就行了

/**
 * 解释xml文件的通用类 对xml文件的格式要求:所有属性均是小写 对实体类的要求:所有属性必须为小写
 *
 * @author Administrator
 *
 */
public class ParsePeron
{
   
    private Person                 currentPerson = null; // ////////////////
    // 需要修改object的类型,以跟XML里面的内容相符//////////////
    private List                   personsList   = null;
    private DocumentBuilderFactory dbf           = null;
    private DocumentBuilder        docBuilder    = null;
    private Document               document      = null;
   
    public ParsePeron(InputStream is)
    {
        this.currentPerson = new Person(); // /////// 这里也需要修改///////////
        personsList = new ArrayList();
        try
        {
            dbf = DocumentBuilderFactory.newInstance();
            docBuilder = dbf.newDocumentBuilder();
            document = docBuilder.parse(is);
        }
        catch (IOException e)
        {
            System.out.println("IO错误!");
            e.printStackTrace();
        }
        catch (SAXException e)
        {
            System.out.println("simple api for xml错误!");
            e.printStackTrace();
        }
        catch (ParserConfigurationException e)
        {
            System.out.println("xml解释配置错误!");
            e.printStackTrace();
        }
    }
   
    public ParsePeron(File file)
    {
        this.currentPerson = new Person(); // ////// 这里也需要修改/////////////
        personsList = new ArrayList();
        Document document = null;
        try
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = dbf.newDocumentBuilder();
            document = docBuilder.parse(file);
        }
        catch (IOException e)
        {
            System.out.println("IO错误!");
            e.printStackTrace();
        }
        catch (SAXException e)
        {
            System.out.println("simple api for xml错误!");
            e.printStackTrace();
        }
        catch (ParserConfigurationException e)
        {
            System.out.println("xml解释配置错误!");
            e.printStackTrace();
        }
    }
   
    public List getPersons()
    {
        generate();
        return personsList;
    }
   
    public Person getPersonByIndex(int index)
    {
        return (Person) (getPersons().get(index)); // 保证取得的是最新的
    }
   
    private void generate()
    {
        NodeList root = document.getChildNodes(); // 根节点
        for (int i = 0; i < root.getLength(); i++)
        {
            Node persons = root.item(i); // persons节点
            NodeList personList = persons.getChildNodes(); // persons下的所有子节点
            for (int j = 0; j < personList.getLength(); j++)
            {
                Node node = personList.item(j); //
                if (node.getNodeType() == Node.ELEMENT_NODE) // 是一个元素节点,在这里也就是person节点
                {
                    try
                    {
                        currentPerson = new Person(); ////////////////这里也需要更改类型/////////////////
                        setDirectProperties(currentPerson, node);
                        setIndirectProperties(currentPerson, node);
                        personsList.add(currentPerson);
                    }
                    catch (Exception e)
                    {
                        System.out.println("不合法的类访问!");
                        e.printStackTrace();
                    }
                }
            }
        }
    }
   
    /**
     * 设置属性,属性相对xml文件中的节点来说是直接属性
     * @param person
     * 接收属性的类实例
     * @param node
     * 直接属性节点
     */
    private void setDirectProperties(Person person, Node node)
    {
        NamedNodeMap attributes = node.getAttributes(); // 这部分获得person的属性
        for (int k = 0; k < attributes.getLength(); k++)
        {
            Node attrNode = attributes.item(k);
            setProperties(person, attrNode);
        }
    }
   
    /**
     * 设置属性,属性相对xml文件中的节点来说是间接属性
     * @param person
     * 接收属性的类实例
     * @param node
     * 间接属性节点
     */
    private void setIndirectProperties(Person person, Node node)
    {
        NodeList subNodes = node.getChildNodes();// 子属性
        for (int k = 0; k < subNodes.getLength(); k++)
        {
            Node attribNode = subNodes.item(k);
            if (attribNode.getNodeType() == Node.ELEMENT_NODE)
            {
                setProperties(person, attribNode);
            }
        }
    }
   
    /**
     *  从xml文件得到数据,设置person的属性
     * @param person
     * 接收数据的Person类实例
     * @param attrNode
     * 直接或间接属性节点
     */
    private void setProperties(Person person, Node attrNode)
    {
       
        Field[] propeties = Person.class.getDeclaredFields();
        for (int i = 0; i < propeties.length; i++)
        {
            String datatypeString = propeties[i].getType().getSimpleName();
            String propertyName = propeties[i].getName();
            if (attrNode.getNodeName().equals(propertyName)) // 对照person.xml理解!!这里指id属性
            {
                Method[] methods = Person.class.getDeclaredMethods(); // //////////////这里的Person也需要改////////////////////
                for (Method method : methods)
                {
                    String methodString = method.getName();
                    if (methodString.indexOf("set") != -1 && methodString.toLowerCase().lastIndexOf(propeties[i].getName()) != -1)
                    {
                        try   //原生类型的转换
                        {
                            Object[] params = null;
                            if (datatypeString.equals("int"))
                            {
                                params = new Object[] { Integer.parseInt(attrNode.getTextContent()) };
                            }
                            if (datatypeString.equals("float"))
                            {
                                params = new Object[] { Float.parseFloat(attrNode.getTextContent()) };
                            }
                            if (datatypeString.equals("double"))
                            {
                                params = new Object[] { Double.parseDouble(attrNode.getTextContent()) };
                            }
                            if (datatypeString.equals("byte"))
                            {
                                params = new Object[] { Byte.parseByte(attrNode.getTextContent()) };
                            }
                            if (datatypeString.equals("short"))
                            {
                                params = new Object[] { Short.parseShort(attrNode.getTextContent()) };
                            }
                            if (datatypeString.equals("long"))
                            {
                                params = new Object[] { Long.parseLong(attrNode.getTextContent()) };
                            }
                            if (datatypeString.equals("char"))
                            {
                                params = new Object[] { Character.valueOf(attrNode.getTextContent().charAt(0)) };
                            }
                            if (datatypeString.equals("boolean"))
                            {
                                params = new Object[] { Boolean.valueOf(attrNode.getTextContent()) };
                            }
                            else if (datatypeString.equals("String"))
                            {
                                params = new Object[] { attrNode.getTextContent() };
                            }
                            method.invoke(person, params);
                            break;
                        }
                        catch (IllegalArgumentException e)
                        {
                            System.out.println("参数不合法!");
                            e.printStackTrace();
                        }
                        catch (IllegalAccessException e)
                        {
                            System.out.println("不合法的访问!");
                            e.printStackTrace();
                        }
                        catch (InvocationTargetException e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
   
    /**
     *
     * @param node
     *            要写入数据的节点
     * @param person
     *            包含数据的类实例
     * @param directProperties
     *            包含类中属性的字符串数组,这个数组将被设置为XML节点中的直接属性
     */
    private void writeDirectProperties(Element node, Person person, String[] directProperties)
    {
        Method[] methods = person.getClass().getDeclaredMethods();
        for (int i = 0; i < directProperties.length; i++)
        {
            for (int j = 0; j < methods.length; j++)
            {
                String temp = methods[j].getName().toLowerCase();
                if (temp.indexOf("get") != -1 && temp.lastIndexOf(directProperties[i]) != -1)
                {
                    try
                    {
                        node.setAttribute(directProperties[i], methods[j].invoke(person, null).toString());
                    }
                    catch (IllegalArgumentException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }
                    catch (InvocationTargetException e)
                    {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }
   
    /**
     *
     * @param node
     *            要写入数据的节点
     * @param person
     *            包含数据的类实例
     * @param directProperties
     *            包含类中属性的字符串数组,这个数组将被设置为XML节点中的间接属性
     */
    private void writeIndirectProperties(Element node, Person person, String[] indirectProperties)
    {
        Method[] methods = person.getClass().getDeclaredMethods();
        for (int i = 0; i < indirectProperties.length; i++)
        {
            for (int j = 0; j < methods.length; j++)
            {
                String temp = methods[j].getName().toLowerCase();
                if (temp.indexOf("get") != -1 && temp.lastIndexOf(indirectProperties[i]) != -1)
                {
                    try
                    {
                        Node subNode = (Node) (document.createElement(indirectProperties[i]));
                        subNode.setTextContent(methods[j].invoke(person, null).toString());
                        node.appendChild(subNode);
                    }
                    catch (IllegalArgumentException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }
                    catch (InvocationTargetException e)
                    {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }
   
    /**
     *
     * @param person
     *            要往XML文件中写入数据的类实例
     * @param directProperties
     *            类实例中的直接属性
     * @param IndirectProperties
     *            类实例中的间接属性
     */
    public void writeNode(Person person, String[] directProperties, String[] indirectProperties)
    {
        Element root = (Element) document.getFirstChild();
       
        Element personElement = document.createElement(person.getClass().getSimpleName().toLowerCase());
        writeDirectProperties(personElement, person, directProperties);
        writeIndirectProperties(personElement, person, indirectProperties);
       
        root.appendChild((Node) personElement);
    }
   
    public void writerToFile(OutputStream outputStream)
    {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer tr;
        try
        {
            tr = transformerFactory.newTransformer();
            tr.setOutputProperty(OutputKeys.INDENT, "yes");
            tr.transform(new DOMSource(document), new StreamResult(outputStream));
        }
        catch (TransformerConfigurationException e)
        {
            System.out.println("转换配置异常!");
            e.printStackTrace();
        }
        catch (TransformerException e)
        {
            System.out.println("转换异常!");
            e.printStackTrace();
        }
    }
}

 

 

 

Test.java

package aa;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

public class Test
{
   
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        File file = new File("F:/person.xml");
        InputStream iStream = null;
        try
        {
            iStream = new FileInputStream(file);
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }

        ParsePeron pp = new ParsePeron(iStream);
        List persons = pp.getPersons();
        for (Object object : persons)
        {
            Person person2 = (Person)object;
            System.out.println("name: " + person2.getName() + "/nage:" + person2.getAge() + "/nid:" +  person2.getId() + "/nsex:" + person2.getSex());
            System.out.println();
        }

        String []direct ={"id"};
        String []indirect = {"name","age","sex"};
        Person person = new Person();
        person.setAge(22);
        person.setName("cxj");
        person.setId(324);
        person.setSex("男");
       
        pp.writeNode(person, direct, indirect);   
        try
        {
            pp.writerToFile(new FileOutputStream(file));
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}

 

希望对诸位有用~~