`
carver
  • 浏览: 49209 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

简捷强大的单文件XML操作工具类

    博客分类:
  • Java
阅读更多

这个是我以前做项目过程中积累下来的XML操作工具类,只有一个类文件,使用的全部是JDK自带的类,简单易用。这个类主要包含了XML的读,写,验证, 转换功能。这个类相比一些开源的XML解释工具(比如:JAXB, JiBX, Digester, Javolution, JDOM)好在,不用写任何配置文件,随到随用,非常方便。适合于项目中XML结构复杂,变化比较快,并且XML文件比较小的解释与生成。

 

源代码

XmlUtils.java

package com.carver.commons.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

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

import com.carver.commons.exception.XmlException;

/**
 * Encapsulating XML common operations.
 *
 * @author carver
 * @since 1.0, Jun 12, 2007
 */
public final class XmlUtils {

    private static final String XMLNS_XSI = "xmlns:xsi";
    private static final String XSI_SCHEMA_LOCATION = "xsi:schemaLocation";
    private static final String LOGIC_YES = "yes";
    private static final String DEFAULT_ENCODE = "UTF-8";
    private static final String REG_INVALID_CHARS = "&#\\d+;";

    /**
     * Creates a new document instance.
     *
     * @return a new document instance
     * @throws XmlException problem creating a new document
     */
    public static Document newDocument() throws XmlException {
        Document doc = null;

        try {
            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                    .newDocument();
        } catch (ParserConfigurationException e) {
            throw new XmlException(e);
        }

        return doc;
    }

    /**
     * Parses the content of the given XML file as an XML document.
     *
     * @param file the XML file instance
     * @return the document instance representing the entire XML document
     * @throws XmlException problem parsing the XML file
     */
    public static Document getDocument(File file) throws XmlException {
        InputStream in = getInputStream(file);
        return getDocument(in);
    }

    /**
     * Parses the content of the given stream as an XML document.
     *
     * @param in the XML file input stream
     * @return the document instance representing the entire XML document
     * @throws XmlException problem parsing the XML input stream
     */
    public static Document getDocument(InputStream in) throws XmlException {
        Document doc = null;

        try {
            DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder();
            doc = builder.parse(in);
        } catch (ParserConfigurationException e) {
            throw new XmlException(e);
        } catch (SAXException e) {
            throw new XmlException(XmlException.XML_PARSE_ERROR, e);
        } catch (IOException e) {
            throw new XmlException(XmlException.XML_READ_ERROR, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // nothing to do
                }
            }
        }

        return doc;
    }

    /**
     * Creates a root element as well as a new document with specific tag name.
     *
     * @param tagName the name of the root element
     * @return a new element instance
     * @throws XmlException problem generating a new document
     */
    public static Element createRootElement(String tagName) throws XmlException {
        Document doc = newDocument();
        Element root = doc.createElement(tagName);
        doc.appendChild(root);
        return root;
    }

    /**
     * Gets the root element from input stream.
     *
     * @param in the XML file input stream
     * @return the root element of parsed document
     * @throws XmlException problem parsing the XML file input stream
     */
    public static Element getRootElementFromStream(InputStream in)
            throws XmlException {
        return getDocument(in).getDocumentElement();
    }

    /**
     * Gets the root element from given XML file.
     *
     * @param fileName the name of the XML file
     * @return the root element of parsed document
     * @throws XmlException problem parsing the XML file
     */
    public static Element getRootElementFromFile(File file)
            throws XmlException {
        return getDocument(file).getDocumentElement();
    }

    /**
     * Gets the root element from the given XML payload.
     *
     * @param payload the XML payload representing the XML file.
     * @return the root element of parsed document
     * @throws XmlException problem parsing the XML payload
     */
    public static Element getRootElementFromString(String payload)
            throws XmlException {
        if (payload == null || payload.trim().length() < 1) {
            throw new XmlException(XmlException.XML_PAYLOAD_EMPTY);
        }

        byte[] bytes = null;

        try {
            bytes = payload.getBytes(DEFAULT_ENCODE);
        } catch (UnsupportedEncodingException e) {
            throw new XmlException(XmlException.XML_ENCODE_ERROR, e);
        }

        InputStream in = new ByteArrayInputStream(bytes);
        return getDocument(in).getDocumentElement();
    }

    /**
     * Gets the descendant elements list from the parent element.
     *
     * @param parent the parent element in the element tree
     * @param tagName the specified tag name
     * @return the NOT NULL descendant elements list
     */
    public static List<Element> getElements(Element parent, String tagName) {
        NodeList nodes = parent.getElementsByTagName(tagName);
        List<Element> elements = new ArrayList<Element>();

        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if (node instanceof Element) {
                elements.add((Element) node);
            }
        }

        return elements;
    }

    /**
     * Gets the immediately descendant element from the parent element.
     *
     * @param parent the parent element in the element tree
     * @param tagName the specified tag name.
     * @return immediately descendant element of parent element, NULL otherwise.
     */
    public static Element getElement(Element parent, String tagName) {
        List<Element> children = getElements(parent, tagName);

        if (children.isEmpty()) {
            return null;
        } else {
            return children.get(0);
        }
    }

    /**
     * Gets the immediately child elements list from the parent element.
     *
     * @param parent the parent element in the element tree
     * @param tagName the specified tag name
     * @return the NOT NULL immediately child elements list
     */
    public static List<Element> getChildElements(Element parent, String tagName) {
        NodeList nodes = parent.getElementsByTagName(tagName);
        List<Element> elements = new ArrayList<Element>();

        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if (node instanceof Element && node.getParentNode() == parent) {
                elements.add((Element) node);
            }
        }

        return elements;
    }

    /**
     * Gets the immediately child element from the parent element.
     *
     * @param parent the parent element in the element tree
     * @param tagName the specified tag name
     * @return immediately child element of parent element, NULL otherwise
     */
    public static Element getChildElement(Element parent, String tagName) {
        List<Element> children = getChildElements(parent, tagName);

        if (children.isEmpty()) {
            return null;
        } else {
            return children.get(0);
        }
    }

    /**
     * Gets the value of the child element by tag name under the given parent
     * element. If there is more than one child element, return the value of the
     * first one.
     *
     * @param parent the parent element
     * @param tagName the tag name of the child element
     * @return value of the first child element, NULL if tag not exists
     */
    public static String getElementValue(Element parent, String tagName) {
        String value = null;

        Element element = getElement(parent, tagName);
        if (element != null) {
            value = element.getTextContent();
        }

        return value;
    }

    /**
     * Appends the child element to the parent element.
     *
     * @param parent the parent element
     * @param tagName the child element name
     * @return the child element added to the parent element
     */
    public static Element appendElement(Element parent, String tagName) {
        Element child = parent.getOwnerDocument().createElement(tagName);
        parent.appendChild(child);
        return child;
    }

    /**
     * Appends the child element as well as value to the parent element.
     *
     * @param parent the parent element
     * @param tagName the child element name
     * @param value the child element value
     * @return the child element added to the parent element
     */
    public static Element appendElement(Element parent, String tagName,
            String value) {
        Element child = appendElement(parent, tagName);
        child.setTextContent(value);
        return child;
    }

    /**
     * Appends another element as a child element.
     *
     * @param parent the parent element
     * @param child the child element to append
     */
    public static void appendElement(Element parent, Element child) {
        Node tmp = parent.getOwnerDocument().importNode(child, true);
        parent.appendChild(tmp);
    }

    /**
     * Appends the CDATA element to the parent element.
     *
     * @param parent the parent element
     * @param tagName the CDATA element name
     * @param value the CDATA element value
     * @return the CDATA element added to the parent element
     */
    public static Element appendCDATAElement(Element parent, String tagName,
            String value) {
        Element child = appendElement(parent, tagName);
        if (value == null) { // avoid "null" word in the XML payload
            value = "";
        }

        Node cdata = child.getOwnerDocument().createCDATASection(value);
        child.appendChild(cdata);
        return child;
    }

    /**
     * Converts the Node/Element instance to XML payload.
     *
     * @param node the node/element instance to convert
     * @return the XML payload representing the node/element
     * @throws XmlException problem converting XML to string
     */
    public static String childNodeToString(Node node) throws XmlException {
        String payload = null;

        try {
            Transformer tf = TransformerFactory.newInstance().newTransformer();

            Properties props = tf.getOutputProperties();
            props.setProperty(OutputKeys.OMIT_XML_DECLARATION, LOGIC_YES);
            tf.setOutputProperties(props);

            StringWriter writer = new StringWriter();
            tf.transform(new DOMSource(node), new StreamResult(writer));
            payload = writer.toString();
            payload = payload.replaceAll(REG_INVALID_CHARS, " ");
        } catch (TransformerException e) {
            throw new XmlException(XmlException.XML_TRANSFORM_ERROR, e);
        }

        return payload;
    }

    /**
     * Converts the Node/Document/Element instance to XML payload.
     *
     * @param node the node/document/element instance to convert
     * @return the XML payload representing the node/document/element
     * @throws XmlException problem converting XML to string
     */
    public static String nodeToString(Node node) throws XmlException {
        String payload = null;

        try {
            Transformer tf = TransformerFactory.newInstance().newTransformer();

            Properties props = tf.getOutputProperties();
            props.setProperty(OutputKeys.INDENT, LOGIC_YES);
            props.setProperty(OutputKeys.ENCODING, DEFAULT_ENCODE);
            tf.setOutputProperties(props);

            StringWriter writer = new StringWriter();
            tf.transform(new DOMSource(node), new StreamResult(writer));
            payload = writer.toString();
            payload = payload.replaceAll(REG_INVALID_CHARS, " ");
        } catch (TransformerException e) {
            throw new XmlException(XmlException.XML_TRANSFORM_ERROR, e);
        }

        return payload;
    }

    /**
     * Converts the an XML file to XML payload.
     *
     * @param file the XML file instance
     * @return the XML payload representing the XML file
     * @throws XmlException problem transforming XML to string
     */
    public static String xmlToString(File file) throws XmlException {
        Element root = getRootElementFromFile(file);
        return nodeToString(root);
    }

    /**
     * Converts the an XML file input stream to XML payload.
     *
     * @param in the XML file input stream
     * @return the payload represents the XML file
     * @throws XmlException problem transforming XML to string
     */
    public static String xmlToString(InputStream in) throws XmlException {
        Element root = getRootElementFromStream(in);
        return nodeToString(root);
    }

    /**
     * Saves the node/document/element as XML file.
     *
     * @param doc the XML node/document/element to save
     * @param file the XML file to save
     * @throws XmlException problem persisting XML file
     */
    public static void saveToXml(Node doc, File file) throws XmlException {
        OutputStream out = null;

        try {
            Transformer tf = TransformerFactory.newInstance().newTransformer();

            Properties props = tf.getOutputProperties();
            props.setProperty(OutputKeys.METHOD, XMLConstants.XML_NS_PREFIX);
            props.setProperty(OutputKeys.INDENT, LOGIC_YES);
            tf.setOutputProperties(props);

            DOMSource dom = new DOMSource(doc);
            out = getOutputStream(file);
            Result result = new StreamResult(out);
            tf.transform(dom, result);
        } catch (TransformerException e) {
            throw new XmlException(XmlException.XML_TRANSFORM_ERROR, e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // nothing to do
                }
            }
        }
    }

    /**
     * Validates the element tree context via given XML schema file.
     *
     * @param doc the XML document to validate
     * @param schemaFile the XML schema file instance
     * @throws XmlException error occurs if the schema file not exists
     */
    public static void validateXml(Node doc, File schemaFile)
            throws XmlException {
        validateXml(doc, getInputStream(schemaFile));
    }

    /**
     * Validates the element tree context via given XML schema file.
     *
     * @param doc the XML document to validate
     * @param schemaStream the XML schema file input stream
     * @throws XmlException error occurs if validation fail
     */
    public static void validateXml(Node doc, InputStream schemaStream)
            throws XmlException {
        try {
            Source source = new StreamSource(schemaStream);
            Schema schema = SchemaFactory.newInstance(
                    XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(source);

            Validator validator = schema.newValidator();
            validator.validate(new DOMSource(doc));
        } catch (SAXException e) {
            throw new XmlException(XmlException.XML_VALIDATE_ERROR, e);
        } catch (IOException e) {
            throw new XmlException(XmlException.XML_READ_ERROR, e);
        } finally {
            if (schemaStream != null) {
                try {
                    schemaStream.close();
                } catch (IOException e) {
                    // nothing to do
                }
            }
        }
    }

    /**
     * Transforms the XML content to XHTML/HTML format string with the XSL.
     *
     * @param payload the XML payload to convert
     * @param xsltFile the XML stylesheet file
     * @return the transformed XHTML/HTML format string
     * @throws XmlException problem converting XML to HTML
     */
    public static String xmlToHtml(String payload, File xsltFile)
            throws XmlException {
        String result = null;

        try {
            Source template = new StreamSource(xsltFile);
            Transformer transformer = TransformerFactory.newInstance()
                    .newTransformer(template);

            Properties props = transformer.getOutputProperties();
            props.setProperty(OutputKeys.OMIT_XML_DECLARATION, LOGIC_YES);
            transformer.setOutputProperties(props);

            StreamSource source = new StreamSource(new StringReader(payload));
            StreamResult sr = new StreamResult(new StringWriter());
            transformer.transform(source, sr);

            result = sr.getWriter().toString();
        } catch (TransformerException e) {
            throw new XmlException(XmlException.XML_TRANSFORM_ERROR, e);
        }

        return result;
    }

    /**
     * Sets the namespace to specific element.
     *
     * @param element the element to set
     * @param namespace the namespace to set
     * @param schemaLocation the XML schema file location URI
     */
    public static void setNamespace(Element element, String namespace,
            String schemaLocation) {
        element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
                XMLConstants.XMLNS_ATTRIBUTE, namespace);
        element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLNS_XSI,
                XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        element.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
                XSI_SCHEMA_LOCATION, schemaLocation);
    }

    /**
     * Encode the XML payload to legality character.
     *
     * @param payload the XML payload to encode
     * @return the encoded XML payload
     * @throws XmlException problem encoding the XML payload
     */
    public static String encodeXml(String payload) throws XmlException {
        Element root = createRootElement(XMLConstants.XML_NS_PREFIX);
        root.setTextContent(payload);
        return childNodeToString(root.getFirstChild());
    }

    private static InputStream getInputStream(File file) throws XmlException {
        InputStream in = null;

        try {
            in = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            throw new XmlException(XmlException.FILE_NOT_FOUND, e);
        }

        return in;
    }

    private static OutputStream getOutputStream(File file) throws XmlException {
        OutputStream in = null;

        try {
            in = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            throw new XmlException(XmlException.FILE_NOT_FOUND, e);
        }

        return in;
    }

}

 XmlException.java

package com.carver.commons.exception;

/**
 * Runtime exception for XML handling.
 *
 * @author carver
 * @since 1.0, Jun 12, 2007
 */
public class XmlException extends RuntimeException {

    private static final long serialVersionUID = 381260478228427716L;

    public static final String XML_PAYLOAD_EMPTY = "xml.payload.empty";
    public static final String XML_ENCODE_ERROR = "xml.encoding.invalid";
    public static final String FILE_NOT_FOUND = "xml.file.not.found";
    public static final String XML_PARSE_ERROR = "xml.parse.error";
    public static final String XML_READ_ERROR = "xml.read.error";
    public static final String XML_VALIDATE_ERROR = "xml.validate.error";
    public static final String XML_TRANSFORM_ERROR = "xml.transform.error";

    public XmlException() {
        super();
    }

    public XmlException(String key, Throwable cause) {
        super(key, cause);
    }

    public XmlException(String key) {
        super(key);
    }

    public XmlException(Throwable cause) {
        super(cause);
    }

}

 

使用示例

user.xml

<user>
    <id>100000</id>
    <nick>carver.gu</nick>
    <email>carver.gu@gmail.com</email>
    <gender>male</gender>
    <contact>
        <address>hangzhou</address>
        <post-code>310019</post-code>
        <telephone>88888888</telephone>
    </contact>
</user>

 解释XML

InputStream in = XmlTest.class.getResourceAsStream("user.xml");
Element root = XmlUtils.getRootElementFromStream(in);
String id = XmlUtils.getElementValue(root, "id");
String nick = XmlUtils.getElementValue(root, "nick");
String email = XmlUtils.getElementValue(root, "email");
String gender = XmlUtils.getElementValue(root, "gender");

Element contactE = XmlUtils.getChildElement(root, "contact");
String address = XmlUtils.getElementValue(contactE, "address");
String postCode = XmlUtils.getElementValue(contactE, "post-code");
String telephone = XmlUtils.getElementValue(contactE, "telephone");

 生成XML

Element root = XmlUtils.createRootElement("user");
XmlUtils.appendElement(root, "id", "100000");
XmlUtils.appendElement(root, "nick", "carver.gu");
XmlUtils.appendElement(root, "email", "carver.gu@gmail.com");
XmlUtils.appendElement(root, "gender", "male");

Element contactE = XmlUtils.appendElement(root, "contact");
XmlUtils.appendElement(contactE, "address", "hangzhou");
XmlUtils.appendElement(contactE, "post-code", "310019");
XmlUtils.appendElement(contactE, "telephone", "88888888");

System.out.println(XmlUtils.nodeToString(root));
 
分享到:
评论
2 楼 不爱吃鱼的猫 2016-09-29  
很好,很强大
1 楼 sdtm1016 2016-05-20  
hi,大神,想问下这个文件我可以在项目中直接用么?

相关推荐

    关闭winXP NT 2003局域网共享最简捷的批处理文件

    简捷方便的 关闭局域网共享的批处理文件! 操作方法:请执行批处理.cmd文件就OK! ====================== 中国电子爱好者论坛www.dzahz.net/bbs搜集整理,欢迎电子爱好者们前来查看更多资源。

    Office 2003与XML

    讨论了XML与Office 2003的关系,检验了Office套件中各个不同的产品是如何创建并共享XML的,先讲述了XML的基本特征,然后提供了对导入信息到Office文档或将Offcie文件的信息导出到其他应用程序中的简捷、清晰的指导,...

    Office 与XML(CHM)

    讨论了XML与Office的关系,检验了Office套件中各个不同的产品是如何创建并共享XML的,先讲述了XML的基本特征,然后提供了对导入信息到Office文档或将Offcie文件的信息导出到其他应用程序中的简捷、清晰的指导

    虚拟光驱V2.0单文件版

    虚拟光驱V2.0单文件版,绿色、简捷,很好用的。

    Office 2003与XML(CHM).rar

    讨论了XML与Office 2003的关系,检验了Office套件中各个不同的产品是如何创建并共享XML的,先讲述了XML的基本特征,然后提供了对导入信息到Office文档或将Offcie文件的信息导出到其他应用程序中的简捷、清晰的指导,...

    CAD简捷命令

    很好用的 很常用的CAD快捷键 文件大小:32.5 KB

    程序员必备简捷开发辅助工具

    内含Beyond Compare,HiJson,Notepad++,Sublime Text,Xmind,Everything 文件搜索查找,编辑,对比,数据格式优化等等(还有注册码哦)

    winXP NT 2003硬盘各分区的默认共享打开和关闭最简捷的批处理文件

    硬盘各分区的默认共享-打开和关闭 操作方法:请执行批处理.cmd文件就OK! ====================== 中国电子爱好者论坛www.dzahz.net/bbs搜集整理,欢迎电子爱好者们前来查看更多资源。

    趣味题与简捷解_李文汉-让你开窍的数学

    趣味题与简捷解_李文汉-让你开窍的数学 趣味题与简捷解_李文汉-让你开窍的数学 趣味题与简捷解_李文汉-让你开窍的数学

    md5算法.可以对文件和字符串计算md5值

    支持对文件和字符串计算MD5值.本程序算法使用C++语言.可以快速计算出文件或字符串得md5值,程序简捷明了

    飞鸽传书最新版本方便的局域网传送文件工具支持文件夹的传送

    是一款完全免费使用的局域网即时通讯工具!...3.软件操作简捷,界面清晰,任意拖曳即可实现操作。 4.自由沟通,自由群发,提高办公效率。 &gt;有很多创新的功能待您体验,赶快下载试用,感受网即通的与众不

    飞鸽传书简捷版

    1、飞鸽传书局域网传输软件,最新支持PC、手机、平板电脑文字、文件、文件夹互传。 2、绿色软件,无需安装,解压即可使用。 3、常用小工具,超级便笺、工作等高效办公管理助手。

    强大的量产工具 UPTool_Ver2061(Release07)20130218

    群联最新量产工具V20130218(UPTool_Ver2061(Release07):自动侦测移动磁盘,可以给U盘分区,制作... 其强大的移动磁盘兼容性和修复功能,量产kingsion最新PS2251-67主控芯片,比PS2251-67量产工具v3.63更强大、简捷。

    XP一键优化,最简捷的一键操作完成对XP系统速度全面提升

    最简捷的一键操作完成对XP系统速度全面提升.软件自带注册表备份功能.

    诗词格律简捷入门

    中华诗词学会专门为第一届中华诗词研修班学员编写的读物。诗词格律不晦涩,最快速入门方法

    洪轩文件管理系统

    文件分类支持任意类 型的文件及文件夹。 (二)资源管理 《洪轩文件管理系统》提供了一款简易的资源管理器,在此管理器中,通 过方便简捷的右键菜单,可以实现系统资源管理器的绝大部分功能,从而更大 程度地方便...

    简捷的键盘扫描去抖方法 简捷的键盘扫描去抖方法

    简捷的键盘扫描去抖方法 简捷的键盘扫描去抖方法 简捷的键盘扫描去抖方法 简捷的键盘扫描去抖方法 简捷的键盘扫描去抖方法

    Office 2003与XML(CHM)

    讨论了XML与Office 2003的关系,检验了Office套件中各个不同的产品是如何创建并共享XML的,先讲述了XML的基本特征,然后提供了对导入信息到Office文档或将Offcie文件的信息导出到其他应用程序中的简捷、清晰的指导,...

    飞鸽传书简捷版 V4.0.120307 绿色版

    飞鸽传书简捷版的主要功能特点有:拥有文字消息传输、文件与文件夹传输;语音通话、建立局域网群组通讯等特点。

    单层索网幕墙中拉索的简捷计算法.docx

    单层索网幕墙中拉索的简捷计算法.docx

Global site tag (gtag.js) - Google Analytics