`
uule
  • 浏览: 6395199 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

XML工具类DOMUtil

 
阅读更多
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Vector;

import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Attr;
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;

/**
 * DOM utility
 * 
 * Thanks to Tom Fennelly from Jboss Group
 * 
 */
public class DOMUtil {
	
	/**
	 * Create a new W3C Document.
	 * <p/>
	 * Handles exceptions etc.
	 * @return The new Document instance.
	 * @throws ConfigurationException 
	 */
	public static Document createDocument() throws ConfigurationException {
		Document doc = null;
		
		try {
			doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		} catch (ParserConfigurationException e) {
			throw new ConfigurationException("Failed to create ESB Configuration Document instance.");
		}
		
		return doc;
	}

    /**
     * Parse the supplied XML String and return the associated W3C Document object.
     *
     * @param xml XML String.
     * @return The W3C Document object associated with the input stream.
     */
    public static Document parse(String xml) throws SAXException, IOException {
        return parseStream(new ByteArrayInputStream(xml.getBytes()), false, false);
    }

    /**
     * Parse the XML stream and return the associated W3C Document object.
     * <p/>
     * Performs a namespace unaware parse.
     *
     * @param stream
     *            The stream to be parsed.
     * @param validate
     *            True if the document is to be validated, otherwise false.
     * @param expandEntityRefs
     *            Expand entity References as per
     *            {@link DocumentBuilderFactory#setExpandEntityReferences(boolean)}.
     * @return The W3C Document object associated with the input stream.
     */
    public static Document parseStream(InputStream stream, boolean validate,
            boolean expandEntityRefs) throws SAXException, IOException {
        return parseStream(stream, validate, expandEntityRefs, false);
    }

    /**
     * Parse the XML stream and return the associated W3C Document object.
     *
     * @param stream
     *            The stream to be parsed.
     * @param validate
     *            True if the document is to be validated, otherwise false.
     * @param expandEntityRefs
     *            Expand entity References as per
     *            {@link DocumentBuilderFactory#setExpandEntityReferences(boolean)}.
     * @param namespaceAware
     *            True if the document parse is to be namespace aware,
     *            otherwise false.
     * @return The W3C Document object associated with the input stream.
     */
    public static Document parseStream(InputStream stream, boolean validate,
            boolean expandEntityRefs, boolean namespaceAware) throws SAXException, IOException {
        if (stream == null) {
            throw new IllegalArgumentException(
                    "null 'stream' arg in method call.");
        }
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder docBuilder = null;

            factory.setValidating(validate);
            factory.setExpandEntityReferences(expandEntityRefs);
            factory.setNamespaceAware(namespaceAware);
            docBuilder = factory.newDocumentBuilder();

            return docBuilder.parse(stream);
        } catch (ParserConfigurationException e) {
            IllegalStateException state = new IllegalStateException(
                    "Unable to parse XML stream - XML Parser not configured correctly.");
            state.initCause(e);
            throw state;
        } catch (FactoryConfigurationError e) {
            IllegalStateException state = new IllegalStateException(
                    "Unable to parse XML stream - DocumentBuilderFactory not configured correctly.");
            state.initCause(e);
            throw state;
        }
    }

    public static String getAttribute(Element element, String name, String defaultVal) {
        if(element.hasAttribute(name)) {
            return element.getAttribute(name);
        } else {
            return defaultVal;
        }
    }

    /**
	 * Add an Element node to the supplied parent name.
	 * @param parent The parent to to which the new Element node is to be added.
	 * @param elementName The name of the Element to be added.
	 * @return The new Element.
	 */
	public static Element addElement(Node parent, String elementName) {
		Element element = null;
		
		if(parent instanceof Document) {
			element = ((Document)parent).createElement(elementName);
		} else {
			element = parent.getOwnerDocument().createElement(elementName);
		}
		parent.appendChild(element);
		
		return element;
	}
	
	/**
	 * Remove all attributes having an empty value.
	 * @param element The element to be processed.
	 */
	public static void removeEmptyAttributes(Element element) {
		NamedNodeMap attributes = element.getAttributes();
		int attribCount = attributes.getLength();
		
		for(int i = attribCount - 1; i >= 0; i--) {
			Attr attribute = (Attr) attributes.item(i);
			
			// Note - doesn't account for namespaces.  Not needed here !
			if(attribute.getValue().equals("")) {
				attributes.removeNamedItem(attribute.getName());
			}
		}
	}

	/**
	 * Serialize the supplied DOM node to the specified file in the specified output directory.
	 * @param node The DOM node to be serialised.
	 * @param outdir The directory into which the file is to be serialised.
	 * @param fileName The name of the file.
	 * @throws ConfigurationException Unable to serialise the node.
	 */
	public static void serialize(Node node, File outdir, String fileName) throws ConfigurationException {
		serialize(node, new StreamResult(new File(outdir, fileName)));
	}

    public static void serialize(Node node, OutputStream out) throws ConfigurationException {
      serialize(node, new StreamResult(out));
    }

    /**
      * Serialize the supplied DOM node to the supplied DOM StreamResult instance.
      * @param node The DOM node to be serialised.
      * @param streamRes The StreamResult into which the node is to be serialised.
      * @throws ConfigurationException Unable to serialise the node.
      */
    public static void serialize(Node node, StreamResult streamRes) throws ConfigurationException {
        serialize(node, streamRes, false);
    }

   /**
	 * Serialize the supplied DOM node to the supplied DOM StreamResult instance.
	 * @param node The DOM node to be serialised.
	 * @param streamRes The StreamResult into which the node is to be serialised.
     * @param omitXmlDecl Omit the XML declaration.
	 * @throws ConfigurationException Unable to serialise the node.
	 */
	public static void serialize(Node node, StreamResult streamRes, boolean omitXmlDecl) throws ConfigurationException {
		DOMSource domSource = new DOMSource(node);
		
		try {
			Transformer transformer = TransformerFactory.newInstance().newTransformer();

            // There's a bug in Java 5 re this code (formatting).
            // See http://forum.java.sun.com/thread.jspa?threadID=562510&start=0 and it explains the
            // whys of the following code.
            // transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "4");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, (omitXmlDecl?"yes":"no"));
			transformer.transform(domSource, streamRes);
		} catch (Exception e) {
			throw new ConfigurationException("Failed to serialize ESB Configuration Document instance.");
		}
	}

    /**
     * Count the DOM element nodes before the supplied node, having the specified
     * tag name, not including the node itself.
     * <p/>
     * Counts the sibling nodes.
     *
     * @param node    Node whose element siblings are to be counted.
     * @param tagName The tag name of the sibling elements to be counted.
     * @return The number of siblings elements before the supplied node with the
     *         specified tag name.
     */
    public static int countElementsBefore(Node node, String tagName) {
        Node parent = node.getParentNode();

        NodeList siblings = parent.getChildNodes();
        int count = 0;
        int siblingCount = siblings.getLength();

        for (int i = 0; i < siblingCount; i++) {
            Node sibling = siblings.item(i);

            if (sibling == node) {
                break;
            }
            if (sibling.getNodeType() == Node.ELEMENT_NODE && ((Element) sibling).getTagName().equals(tagName)) {
                count++;
            }
        }

        return count;
    }

    /**
     * Copy the nodes of a NodeList into the supplied list.
     * <p/>
     * This is not a cloneCollectionTemplateElement.  It's just a copy of the node references.
     * <p/>
     * Allows iteration over the Nodelist using the copy in the knowledge that
     * the list will remain the same length, even if we modify the underlying NodeList.
     * Using the NodeList can result in problems because elements can get removed from
     * the list while we're iterating over it.
     * <p/>
     * <i>This code was acquired donated by the Milyn Smooks project.</i>
     *
     * @param nodeList Nodelist to copy.
     * @return List copy.
     */
    public static List<Node> copyNodeList(NodeList nodeList) {
        List<Node> copy = new Vector<Node>();

        if (nodeList != null) {
            int nodeCount = nodeList.getLength();

            for (int i = 0; i < nodeCount; i++) {
                copy.add(nodeList.item(i));
            }
        }

        return copy;
    }
    
    public static Element getNextSiblingElement(Node node) {
        Node nextSibling = node.getNextSibling();

        while (nextSibling != null) {
            if (nextSibling.getNodeType() == Node.ELEMENT_NODE) {
                return (Element) nextSibling;
            }
            nextSibling = nextSibling.getNextSibling();
        }

        return null;
    }

    public static Node getFirstChildByType(Element element, int nodeType) {
        NodeList children = element.getChildNodes();
        int childCount = children.getLength();

        for(int i = 0; i < childCount; i++) {
            Node child = children.item(i);
            if (child.getNodeType() == nodeType) {
                return child;
            }
        }

        return null;
    }

    private static String ELEMENT_NAME_FUNC = "/name()";

    private static XPathFactory xPathFactory = XPathFactory.newInstance();

    /**
     * Get the W3C NodeList instance associated with the XPath selection
     * supplied.
     * <p/>
     * <b>NOTE</b>: Taken from Milyn Commons.
     *
     * @param node  The document node to be searched.
     * @param xpath The XPath String to be used in the selection.
     * @return The W3C NodeList instance at the specified location in the
     *         document, or null.
     */
    public static NodeList getNodeList(Node node, String xpath) {
        if (node == null) {
            throw new IllegalArgumentException(
                    "null 'document' arg in method call.");
        } else if (xpath == null) {
            throw new IllegalArgumentException(
                    "null 'xpath' arg in method call.");
        }
        try {
            XPath xpathEvaluater = xPathFactory.newXPath();

            if (xpath.endsWith(ELEMENT_NAME_FUNC)) {
                return (NodeList) xpathEvaluater.evaluate(xpath.substring(0,
                        xpath.length() - ELEMENT_NAME_FUNC.length()), node,
                        XPathConstants.NODESET);
            } else {
                return (NodeList) xpathEvaluater.evaluate(xpath, node,
                        XPathConstants.NODESET);
            }
        } catch (XPathExpressionException e) {
            throw new IllegalArgumentException("bad 'xpath' expression ["
                    + xpath + "].");
        }
    }

    /**
     * Get the W3C Node instance associated with the XPath selection supplied.
     * <p/>
     * <b>NOTE</b>: Taken from Milyn Commons.
     *
     * @param node  The document node to be searched.
     * @param xpath The XPath String to be used in the selection.
     * @return The W3C Node instance at the specified location in the document,
     *         or null.
     */
    public static Node getNode(Node node, String xpath) {
        NodeList nodeList = getNodeList(node, xpath);

        if (nodeList == null || nodeList.getLength() == 0) {
            return null;
        } else {
            return nodeList.item(0);
        }
    }

    /**
     * Get the name from the supplied element.
     * <p/>
     * Returns the {@link Node#getLocalName() localName} of the element
     * if set (namespaced element), otherwise the
     * element's {@link Element#getTagName() tagName} is returned.
     * <p/>
     * <b>NOTE</b>: Taken from Milyn Smooks.
     *
     * @param element The element.
     * @return The element name.
     */
    public static String getName(Element element) {

        String name = element.getLocalName();

        if(name != null) {
            return name;
        } else {
            return element.getTagName();
        }
    }
    /**
     * Copy child node references from source to target.
     * @param source Source Node.
     * @param target Target Node.
     */
    public static void copyChildNodes(Node source, Node target) {
        
        List nodeList = copyNodeList(source.getChildNodes());
        int childCount = nodeList.size();
        
        for(int i = 0; i < childCount; i++) {
            target.appendChild((Node)nodeList.get(i));
        }
    }

}

 

分享到:
评论

相关推荐

    电影院售票管理系统.doc

    - `util` 包通常存放工具类,这里的`DomUtil`是处理XML文档的工具类,提供了读取和保存XML文件的方法。 - `test` 包通常用于存放测试类,`Start`类可能是测试应用程序的主入口点。 - `service` 包则包含了业务...

    (源码)基于Python和Arduino框架的LightBox项目.zip

    # 基于Python和Arduino框架的LightBox项目 ## 项目简介 LightBox是一个结合了Arduino硬件、Python服务器端脚本和Python客户端脚本的项目。它旨在通过LED灯的状态反馈开发者的编译进程状态,从而提高开发效率。当编译过程出现错误或警告时,LightBox会根据情况改变LED灯的颜色,提醒开发者注意。 ## 项目的主要特性和功能 1. Arduino硬件电路使用Atmega 168芯片,通过Arduino编程控制RGB LED的状态以及外部传感器数据的读取和处理。支持随机颜色模式、命令模式等,并能通过串行端口与外部进行通信。 2. Python服务器脚本负责接收客户端的命令,并通过串行端口发送给Arduino硬件电路。同时,它还可以启动一个UDP服务器,等待客户端的连接和命令。

    使用homeassistant 插件将tasmota 接入到米家

    使用homeassistant 插件将tasmota 接入到米家

    (源码)基于Spring和MyBatis Plus的敏捷工贸公司销售管理系统.zip

    # 基于Spring和MyBatis Plus的敏捷工贸公司销售管理系统 ## 项目简介 本项目是一个基于Web的敏捷工贸公司销售管理系统,采用Spring和MyBatis Plus框架开发,前端使用Vue框架。系统旨在为管理员和员工提供操作平台,实现销售管理、库存管理、订单管理等核心功能,促进公司销售行业的信息化管理。 ## 项目的主要特性和功能 1. 用户管理包含用户登录、注册、退出、密码重置等功能,同时支持用户信息的查询、保存、更新和删除操作,不同角色(管理员、员工等)拥有不同权限。 2. 公告管理可进行公告信息的分页查询、详情查看、保存、更新、删除以及批量上传功能。 3. 客户管理实现客户信息的分页展示、详情获取、保存、更新、删除以及批量导入功能。 4. 物资管理涵盖物资列表查询、详情查询、保存、修改、删除,还支持批量上传物资数据。 5. 物资订单管理提供物资订单列表查询、详情查询、保存、修改、删除等功能。

    数据库管理系统是一个基于Python开发的完整数据库管理解决方案,采用SQLite作为后端数据库,tkinter和ttkbootstrap作为前端GUI框架 系统提供了用户管理、数据表管理、数据操作、

    数据库管理系统是一个基于Python开发的完整数据库管理解决方案,采用SQLite作为后端数据库,tkinter和ttkbootstrap作为前端GUI框架。系统提供了用户管理、数据表管理、数据操作、导入导出等完整的数据库管理功能。

    【东吴证券】建筑材料行业跟踪周报:关税冲击下首选内需消费-2025-04-06.pdf

    【东吴证券】建筑材料行业跟踪周报:关税冲击下首选内需消费-2025-04-06

    东北大学人工智能20级算法课设.zip

    东北大学人工智能20级算法课设.zip

    电子商务_Java高并发_Redis缓存优化_数据库设计_秒杀系统_分布式事务_性能调优_登录验证_密码加密_参数校验_订单处理_商品库存管理_支付系统_前端交互_后端API_系统.zip

    电子商务_Java高并发_Redis缓存优化_数据库设计_秒杀系统_分布式事务_性能调优_登录验证_密码加密_参数校验_订单处理_商品库存管理_支付系统_前端交互_后端API_系统

    185659数值分析(五)(李庆扬清华).zip

    185659数值分析(五)(李庆扬清华).zip

    LMH6515全差分放大器在400MHz高频应用中的设计与优化

    内容概要:本文档介绍了美国国家半导体公司的LMH6515全差分放大器,适用于高达400 MHz的信号路径应用。该放大器具有200Ω的输入阻抗,A类输出级,支持卓越的低失真性能和线性度,适合作为电压放大器和ADC驱动器。文中详细讨论了LMH6515的输入和输出特性,包括输入阻抗、输出共模电压设定方法、增益控制机制及其与ADC的接口方式。此外,还探讨了不同负载条件下的带宽表现、电感的选择和布局技巧,以及电源和封装方面的注意事项。 适合人群:电子工程技术人员,尤其是从事射频、模拟电路设计的专业人士。 使用场景及目标:①用于设计和优化高性能、高频率的差分放大器电路;②帮助工程师理解和解决实际应用中的技术难题,如失真、带宽和增益控制等问题;③指导工程师在具体应用场景中选择合适的参数配置和元件搭配,以实现最佳性能。 其他说明:文档强调了LMH6515在高频应用中的优势,特别是在与ADC配合使用时的表现。同时提醒使用者关注关键参数的设定和电路板布局的影响,以确保系统的稳定性和可靠性。

    210021102244.pdf

    210021102244.pdf

    YOLOv10-PyQt5-GUI识别各类害虫-检测农业害虫防治和生态环境保护+数据集+训练好的模型+pyqt5可视化界面.zip

    YOLOv10-PyQt5-GUI识别各类害虫-检测农业害虫防治和生态环境保护+数据集+训练好的模型+pyqt5可视化界面包含pyqt可视化界面,有使用教程 1. 内部包含标注好的目标检测数据集,分别有yolo格式(txt文件)和voc格式标签(xml文件), 共717张图像, 已划分好数据集train,val, test,并附有data.yaml文件可直接用于yolov5,v8,v9,v10,v11,v12等算法的训练; 2. yolo目标检测数据集类别名:pests(害虫),包括 Agrotis(夜蛾属)、Athetis_lepigone(一种 moth)、Athetis_lineosa(另一种 moth)、Chilo_suppressalis(螟虫)、Cnaphalocrocis_medinalis_Guenee(一种害虫)、Creatonotus_transiens(一种 moth)、Diaphania_indica(一种螟虫)、Endotricha_consocia(一种 moth)、Euproctis_sparsa(一种 moth)、Gryllidae(蟋蟀科)、Gryllotalpidae(蝼蛄科)、Helicoverpa_armigera(棉铃虫)、Holotrichia_oblita_Faldermann(一种金龟子)、Loxostege_sticticalis(一种 moth)、Mamestra_brassicae(菜青虫)、Maruca_testulalis_Geyer(一种 moth)、Mythimna_separata(粘虫)、Naranga_aenescens_Moore(一种 moth)、Nilaparvata(一种蚜虫)、Paracymoriza_taiwanalis(一种 moth)、Sesamia_inferens(玉米螟)、Sirthe

    一个用ssh整合的员工信息查询系统.zip

    一个用ssh整合的员工信息查询系统.zip

    基于Qt+C++实现的医院信息管理系统+源码+项目文档+数据库(毕业设计&课设&项目开发)

    基于C++和Qt实现的医院信息管理系统+源码+项目文档+数据库,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用。详情见md文档~ 语言C++,开发平台QT,数据库Mysql 2.软件设计包含医生、病人、药物和病例症状等的信息存储和管理 3.搭载智能治疗平台,可以通过输入病症匹配出最可能的患病列表 4.当确认病例时,可以推荐治疗方案,协助医生诊断 5.系统后台结合病例、药物等数据进行统计分析,给予预测或警报 基于C++和Qt实现的医院信息管理系统+源码+项目文档+数据库,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用。详情见md文档 语言C++,开发平台QT,数据库Mysql 2.软件设计包含医生、病人、药物和病例症状等的信息存储和管理 3.搭载智能治疗平台,可以通过输入病症匹配出最可能的患病列表 4.当确认病例时,可以推荐治疗方案,协助医生诊断 5.系统后台结合病例、药物等数据进行统计分析,给予预测或警报~

    【嵌入式系统开发】合作协议书:明确双方权利义务及开发交付流程

    内容概要:本文档是关于嵌入式系统开发的合作协议书,详细规定了甲乙双方在嵌入式系统开发项目中的权利、义务、开发内容、交付时间、费用支付、保密条款、争议解决等方面的内容。甲方(嵌入式系统开发者)负责根据乙方(嵌入式系统需求方)的需求,开发包括硬件设计、软件开发、系统集成等在内的嵌入式系统,并确保系统符合法律法规、行业标准及乙方业务需求,具有稳定性、安全性、可靠性。乙方需提供详细需求文档,配合开发,按时支付费用并对系统进行验收。文档还明确了费用支付方式、违约责任、争议解决机制等,确保双方权益得到保障。 适合人群:嵌入式系统开发公司、需求方企业、法律顾问等相关人员。 使用场景及目标:①为嵌入式系统开发项目提供详细的合同模板,确保双方权利义务明确;②为开发过程中的各个环节提供指导,包括开发内容、交付时间、费用支付等;③为可能出现的争议提供解决机制,确保项目顺利进行。 其他说明:文档包含多个附件,如需求文档、设计方案、技术规格等,这些附件与主协议具有同等法律效力,共同构成完整的合同文件。双方应妥善保管附件,并在合同履行过程中共同遵守其中的约定。如有附件内容与主协议正文冲突,以主协议正文为准。

    【世界卫生组织】WHO Academy investment case-2025-04-01.pdf

    【世界卫生组织】WHO Academy investment case-2025-04-01

    编译器设计-Python实现-有限状态机-词法分析引擎.py 编译器设计-Python实现-数据结构-词法单元类.py 编译器设计-Python实现-枚举类型-词法单元类型.py

    本资源隶属于编译器设计知识领域,采用Python实现与Tkinter GUI开发技术,核心内容聚焦有限状态机模型与词法单元识别算法,专为编程语言词法分析教学与编译器前端开发设计。资源包含完整的状态转换引擎实现、带语法高亮的源代码编辑器组件及多维度分析结果可视化模块,提供语法规则配置接口和错误定位机制,适用于计算机编译原理课程实验、编程语言原型开发及代码静态分析工具构建等场景。通过模块化的词法分析API与交互式GUI演示系统,有效降低编译器技术学习曲线,提升语言处理实践能力。

    【SensorTower】2025年亚太发行商非游戏应用市场洞察-2025-02-18.pdf

    【SensorTower】2025年亚太发行商非游戏应用市场洞察-2025-02-18

    (源码)基于Phalcon框架的快速后台管理系统.zip

    # 基于Phalcon框架的快速后台管理系统 ## 项目简介 本项目是一款基于Phalcon框架的快速后台开发管理框架,专为开发者提供高效的后台管理系统解决方案。通过内置的MVC生成器,开发者可以快速生成控制器、模型、视图及操作菜单,从而将更多精力集中在系统业务逻辑的开发上。系统还提供了完整的管理员权限管理、后台菜单管理、基础用户管理及附件管理等功能,帮助开发者快速搭建功能完善的后台管理系统。 ## 项目的主要特性和功能 1. MVC生成器通过设计数据表,一键生成控制器、模型、视图及操作菜单,极大提升开发效率。 2. 管理员权限管理提供完整的权限管理功能,支持角色分配和权限控制,确保系统安全。 3. 后台菜单管理支持动态管理后台菜单,方便管理员根据需求调整系统功能。 4. 基础用户管理提供用户管理功能,支持用户信息的增删改查及权限分配。 5. 附件管理支持文件上传和管理,方便系统处理附件资源。

Global site tag (gtag.js) - Google Analytics