一、前言
通过tomcat源码包中的org.apache.tomcat.util.DomUtil解析xml工具类,对转org.w3c.dom.Node节点元素为字符串、获取xml的子节点元素、对节点元素属性进行增删改、读取xml文件输入流文档结构对象等。
二、源码示例
package org.apache.tomcat.util;@b@@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.OutputStream;@b@import java.io.StringReader;@b@@b@import javax.xml.parsers.DocumentBuilder;@b@import javax.xml.parsers.DocumentBuilderFactory;@b@import javax.xml.parsers.ParserConfigurationException;@b@import javax.xml.transform.OutputKeys;@b@import javax.xml.transform.Transformer;@b@import javax.xml.transform.TransformerException;@b@import javax.xml.transform.TransformerFactory;@b@import javax.xml.transform.dom.DOMSource;@b@import javax.xml.transform.stream.StreamResult;@b@@b@import org.w3c.dom.Document;@b@import org.w3c.dom.NamedNodeMap;@b@import org.w3c.dom.Node;@b@import org.xml.sax.EntityResolver;@b@import org.xml.sax.InputSource;@b@import org.xml.sax.SAXException;@b@@b@@b@/**@b@ * Few simple utils to read DOM@b@ *@b@ * @author Costin Manolache@b@ *@b@ * @deprecated Unused: Will be removed in Tomcat 8.0.x@b@ */@b@@Deprecated@b@public class DomUtil {@b@ private static final org.apache.juli.logging.Log log=@b@ org.apache.juli.logging.LogFactory.getLog( DomUtil.class );@b@@b@ // -------------------- DOM utils --------------------@b@@b@ /** Get the trimmed text content of a node or null if there is no text@b@ */@b@ public static String getContent(Node n ) {@b@ if( n==null ) return null;@b@ Node n1=DomUtil.getChild(n, Node.TEXT_NODE);@b@@b@ if( n1==null ) return null;@b@@b@ String s1=n1.getNodeValue();@b@ return s1.trim();@b@ }@b@@b@ /** Get the first element child.@b@ * @param parent lookup direct children@b@ * @param name name of the element. If null return the first element.@b@ */@b@ public static Node getChild( Node parent, String name ) {@b@ if( parent==null ) return null;@b@ Node first=parent.getFirstChild();@b@ if( first==null ) return null;@b@@b@ for (Node node = first; node != null;@b@ node = node.getNextSibling()) {@b@ //System.out.println("getNode: " + name + " " + node.getNodeName());@b@ if( node.getNodeType()!=Node.ELEMENT_NODE)@b@ continue;@b@ if( name != null &&@b@ name.equals( node.getNodeName() ) ) {@b@ return node;@b@ }@b@ if( name == null ) {@b@ return node;@b@ }@b@ }@b@ return null;@b@ }@b@@b@ public static String getAttribute(Node element, String attName ) {@b@ NamedNodeMap attrs=element.getAttributes();@b@ if( attrs==null ) return null;@b@ Node attN=attrs.getNamedItem(attName);@b@ if( attN==null ) return null;@b@ return attN.getNodeValue();@b@ }@b@@b@ public static void setAttribute(Node node, String attName, String val) {@b@ NamedNodeMap attributes=node.getAttributes();@b@ Node attNode=node.getOwnerDocument().createAttribute(attName);@b@ attNode.setNodeValue( val );@b@ attributes.setNamedItem(attNode);@b@ }@b@@b@ public static void removeAttribute( Node node, String attName ) {@b@ NamedNodeMap attributes=node.getAttributes();@b@ attributes.removeNamedItem(attName);@b@ }@b@@b@@b@ /** Set or replace the text value@b@ */@b@ public static void setText(Node node, String val) {@b@ Node chld=DomUtil.getChild(node, Node.TEXT_NODE);@b@ if( chld == null ) {@b@ Node textN=node.getOwnerDocument().createTextNode(val);@b@ node.appendChild(textN);@b@ return;@b@ }@b@ // change the value@b@ chld.setNodeValue(val);@b@ }@b@@b@ /** Find the first direct child with a given attribute.@b@ * @param parent@b@ * @param elemName name of the element, or null for any@b@ * @param attName attribute we're looking for@b@ * @param attVal attribute value or null if we just want any@b@ */@b@ public static Node findChildWithAtt(Node parent, String elemName,@b@ String attName, String attVal) {@b@@b@ Node child=DomUtil.getChild(parent, Node.ELEMENT_NODE);@b@ if( attVal== null ) {@b@ while( child!= null &&@b@ ( elemName==null || elemName.equals( child.getNodeName())) &&@b@ DomUtil.getAttribute(child, attName) != null ) {@b@ child=getNext(child, elemName, Node.ELEMENT_NODE );@b@ }@b@ } else {@b@ while( child!= null &&@b@ ( elemName==null || elemName.equals( child.getNodeName())) &&@b@ ! attVal.equals( DomUtil.getAttribute(child, attName)) ) {@b@ child=getNext(child, elemName, Node.ELEMENT_NODE );@b@ }@b@ }@b@ return child;@b@ }@b@@b@@b@ /** Get the first child's content ( ie it's included TEXT node ).@b@ */@b@ public static String getChildContent( Node parent, String name ) {@b@ Node first=parent.getFirstChild();@b@ if( first==null ) return null;@b@ for (Node node = first; node != null;@b@ node = node.getNextSibling()) {@b@ //System.out.println("getNode: " + name + " " + node.getNodeName());@b@ if( name.equals( node.getNodeName() ) ) {@b@ return getContent( node );@b@ }@b@ }@b@ return null;@b@ }@b@@b@ /** Get the first direct child with a given type@b@ */@b@ public static Node getChild( Node parent, int type ) {@b@ Node n=parent.getFirstChild();@b@ while( n!=null && type != n.getNodeType() ) {@b@ n=n.getNextSibling();@b@ }@b@ if( n==null ) return null;@b@ return n;@b@ }@b@@b@ /** Get the next sibling with the same name and type@b@ */@b@ public static Node getNext( Node current ) {@b@ String name=current.getNodeName();@b@ int type=current.getNodeType();@b@ return getNext( current, name, type);@b@ }@b@@b@ /** Return the next sibling with a given name and type@b@ */@b@ public static Node getNext( Node current, String name, int type) {@b@ Node first=current.getNextSibling();@b@ if( first==null ) return null;@b@@b@ for (Node node = first; node != null;@b@ node = node.getNextSibling()) {@b@@b@ if( type >= 0 && node.getNodeType() != type ) continue;@b@ //System.out.println("getNode: " + name + " " + node.getNodeName());@b@ if( name==null )@b@ return node;@b@ if( name.equals( node.getNodeName() ) ) {@b@ return node;@b@ }@b@ }@b@ return null;@b@ }@b@@b@ public static class NullResolver implements EntityResolver {@b@ @Override@b@ public InputSource resolveEntity (String publicId,@b@ String systemId)@b@ throws SAXException, IOException@b@ {@b@ if( log.isTraceEnabled())@b@ log.trace("ResolveEntity: " + publicId + " " + systemId);@b@ return new InputSource(new StringReader(""));@b@ }@b@ }@b@@b@ public static void setAttributes( Object o, Node parent)@b@ {@b@ NamedNodeMap attrs=parent.getAttributes();@b@ if( attrs==null ) return;@b@@b@ for (int i=0; i<attrs.getLength(); i++ ) {@b@ Node n=attrs.item(i);@b@ String name=n.getNodeName();@b@ String value=n.getNodeValue();@b@@b@ if( log.isTraceEnabled() )@b@ log.trace("Attribute " + parent.getNodeName() + " " +@b@ name + "=" + value);@b@ try {@b@ IntrospectionUtils.setProperty(o, name, value);@b@ } catch( Exception ex ) {@b@ ex.printStackTrace();@b@ }@b@ }@b@ }@b@@b@ /** Read XML as DOM.@b@ */@b@ public static Document readXml(InputStream is)@b@ throws SAXException, IOException, ParserConfigurationException@b@ {@b@ DocumentBuilderFactory dbf =@b@ DocumentBuilderFactory.newInstance();@b@@b@ dbf.setValidating(false);@b@ dbf.setIgnoringComments(false);@b@ dbf.setIgnoringElementContentWhitespace(true);@b@ //dbf.setCoalescing(true);@b@ //dbf.setExpandEntityReferences(true);@b@@b@ DocumentBuilder db = null;@b@ db = dbf.newDocumentBuilder();@b@ db.setEntityResolver( new NullResolver() );@b@@b@ // db.setErrorHandler( new MyErrorHandler());@b@@b@ Document doc = db.parse(is);@b@ return doc;@b@ }@b@@b@ public static void writeXml( Node n, OutputStream os )@b@ throws TransformerException@b@ {@b@ TransformerFactory tf=TransformerFactory.newInstance();@b@ //identity@b@ Transformer t=tf.newTransformer();@b@ t.setOutputProperty(OutputKeys.INDENT, "yes");@b@ t.transform(new DOMSource( n ), new StreamResult( os ));@b@ }@b@}