Package cn.org.rapid_framework.generator.util

Source Code of cn.org.rapid_framework.generator.util.XMLHelper

package cn.org.rapid_framework.generator.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.CDATASection;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* 将xml解析成NodeData,NodeData主要是使用Map及List来装attribute
*
* 使用:
* <pre>
*     NodeData nd = XMLHelper.parseXML(inputStream)
* </pre>
* @author badqiu
*/
public class XMLHelper {

    public static class NodeData {
        public String nodeName;
        public String nodeValue;
        public String innerXML;
        public String outerXML;
//        public String innerText;
//        public String outerText;
        public LinkedHashMap<String,String> attributes = new LinkedHashMap<String,String>();
        public List<NodeData> childs = new ArrayList<NodeData>();
       
        public String toString() {
            return "nodeName="+nodeName+",attributes="+attributes+" nodeValue="+nodeValue+" child:\n"+childs;
        }
       
        public LinkedHashMap<String,String> nodeNameAsAttributes(String nodeNameKey) {
          LinkedHashMap map = new LinkedHashMap();
            map.putAll(attributes);
            map.put(nodeNameKey, nodeName);
            return map;
        }
       
        public List<LinkedHashMap<String,String>> childsAsListMap() {
          List<LinkedHashMap<String,String>> result = new ArrayList();
            for(NodeData c : childs) {
              LinkedHashMap map = new LinkedHashMap();
              map.put(c.nodeName, c.nodeValue);
              result.add(map);
            }
            return result;
        }
    }
   
    public static class SimpleXmlParser {
      public static Document getLoadingDoc(String file) throws FileNotFoundException, SAXException, IOException{
        return getLoadingDoc(new FileInputStream(file));
      }
     
        static Document getLoadingDoc(InputStream in) throws SAXException,IOException {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setIgnoringElementContentWhitespace(false);
            dbf.setValidating(false);
            dbf.setCoalescing(false)//convert CDATA nodes to Text
            dbf.setIgnoringComments(false); //为false时与CDATA冲突
            try {
                DocumentBuilder db = dbf.newDocumentBuilder();
               
                //ignore entity resolver
                db.setEntityResolver(new EntityResolver() {
                    public InputSource resolveEntity(String publicId,
                                                     String systemId)
                                                                     throws SAXException,
                                                                     IOException {
                        InputSource is = new InputSource(new StringReader(""));
                        is.setSystemId(systemId);
                        return is;
                    }
                });
               
                InputSource is = new InputSource(in);
                return db.parse(is);
            } catch (ParserConfigurationException x) {
                throw new Error(x);
            }
        }     
      private static NodeData treeWalk(Element elm) {
          NodeData nodeData = new NodeData();
          nodeData.attributes = attrbiuteToMap(elm.getAttributes());
          nodeData.nodeName = elm.getNodeName();
          nodeData.childs = new ArrayList<NodeData>();
          nodeData.innerXML = childsAsText(elm, new StringBuffer(),true).toString();
          nodeData.outerXML = nodeAsText(elm,new StringBuffer(),true).toString();
          nodeData.nodeValue = getNodeValue(elm);
  //        nodeData.innerText = childsAsText(elm, new StringBuffer(),false).toString();
  //        nodeData.outerText = nodeAsText(elm,new StringBuffer(),false).toString();
          NodeList childs = elm.getChildNodes();
          for(int i = 0; i < childs.getLength() ; i++) {
              Node node = childs.item(i);
              if(node.getNodeType() == Node.ELEMENT_NODE) {
                  nodeData.childs.add(treeWalk((Element)node));
              }
          }
          return nodeData;
      }
 
    private static StringBuffer childsAsText(Element elm, StringBuffer sb,boolean ignoreComments) {
      NodeList childs = elm.getChildNodes();
          for(int i = 0; i < childs.getLength() ; i++) {
              Node child = childs.item(i);
              nodeAsText(child,sb,ignoreComments);
          }
          return sb;
    }     
     
      private static StringBuffer nodeAsText(Node elm,StringBuffer sb,boolean ignoreComments) {
         if(elm.getNodeType() == Node.CDATA_SECTION_NODE) {
           CDATASection cdata = (CDATASection)elm;
           sb.append("<![CDATA[");
           sb.append(cdata.getData());
           sb.append("]]>");
           return sb;
         }
         if(elm.getNodeType() == Node.COMMENT_NODE) {
           if(ignoreComments) {
             return sb;
           }
           Comment c = (Comment)elm;
           sb.append("<!--");
           sb.append(c.getData());
           sb.append("-->");
           return sb;
         }
         if(elm.getNodeType() == Node.TEXT_NODE) {
           Text t = (Text)elm;
           sb.append(StringHelper.escapeXml(t.getData(),"<&"));
           return sb;
         }
         NodeList childs = elm.getChildNodes();
         sb.append("<"+elm.getNodeName());
         attributes2String(elm, sb);
         if(childs.getLength() > 0) {
             sb.append(">");
               for(int i = 0; i < childs.getLength() ; i++) {
                   Node child = childs.item(i);
                   nodeAsText(child,sb,ignoreComments);
               }
               sb.append("</"+elm.getNodeName()+">");
         }else {
             sb.append("/>");
         }
         return sb;
    }
 
    private static void attributes2String(Node elm, StringBuffer sb) {
      NamedNodeMap attributes = elm.getAttributes();
           if(attributes != null && attributes.getLength() > 0) {
             sb.append(" ");
               for(int j = 0; j < attributes.getLength(); j++) {
                   sb.append(String.format("%s=\"%s\"", attributes.item(j).getNodeName(), StringHelper.escapeXml(attributes.item(j).getNodeValue(),"<&\"")));
                   if(j < attributes.getLength() - 1) {
                     sb.append(" ");
                   }
               }
           }
    }
    }

  public static LinkedHashMap<String,String> attrbiuteToMap(NamedNodeMap attributes) {
        if(attributes == null) return new LinkedHashMap<String,String>();
        LinkedHashMap<String,String> result = new LinkedHashMap<String,String>();
        for(int i = 0; i < attributes.getLength(); i++) {
            result.put(attributes.item(i).getNodeName(), attributes.item(i).getNodeValue());
        }
        return result;
    }
   
     /**
     * Extract the text value from the given DOM element, ignoring XML comments. <p>Appends all CharacterData nodes and
     * EntityReference nodes into a single String value, excluding Comment nodes.
     *
     * @see CharacterData
     * @see EntityReference
     * @see Comment
     */
    public static String getTextValue(Element valueEle) {
        if(valueEle == null) throw new IllegalArgumentException("Element must not be null");
        StringBuilder sb = new StringBuilder();
        NodeList nl = valueEle.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node item = nl.item(i);
            if ((item instanceof CharacterData && !(item instanceof Comment)) || item instanceof EntityReference) {
                sb.append(item.getNodeValue());
            }else if(item instanceof Element) {
                sb.append(getTextValue((Element)item));
            }
        }
        return sb.toString();
    }
   
    public static String getNodeValue(Node node) {
        if(node instanceof Comment){
            return null;
        }
        if(node instanceof CharacterData) {
            return ((CharacterData)node).getData();
        }
        if(node instanceof EntityReference) {
            return node.getNodeValue();
        }
        if(node instanceof Element) {
            return getTextValue((Element)node);
        }
        return node.getNodeValue();
    }
   
    public NodeData parseXML(InputStream in) throws SAXException, IOException {
        Document doc = SimpleXmlParser.getLoadingDoc(in);
        return new SimpleXmlParser().treeWalk(doc.getDocumentElement());
    }

    public NodeData parseXML(File file) throws SAXException, IOException {
        FileInputStream in = new FileInputStream(file);
    try {return parseXML(in);}finally{in.close();}
    }
   
    public static String getXMLEncoding(InputStream inputStream) throws UnsupportedEncodingException, IOException {
      return getXMLEncoding(IOHelper.toString("UTF-8", inputStream));
    }
   
    public static String getXMLEncoding(String s) {
      if(s == null) return null;
      Pattern p = Pattern.compile("<\\?xml.*encoding=[\"'](.*)[\"']\\?>");
      Matcher m = p.matcher(s);
      if(m.find()) {
        return m.group(1);
      }
      return null;
    }

    public static String removeXmlns(File file) throws IOException {
        InputStream forEncodingInput = new FileInputStream(file);
        String encoding = XMLHelper.getXMLEncoding(forEncodingInput);
        forEncodingInput.close();
       
        InputStream input = new FileInputStream(file);
        String xml = IOHelper.toString(encoding,input);
        xml = XMLHelper.removeXmlns(xml);
        input.close();
        return xml;
    }
   
    //只移除default namesapce
    public static String removeXmlns(String s) {
      if(s == null) return null;
      s = s.replaceAll("(?s)xmlns=['\"].*?['\"]", "");
//      s = s.replaceAll("(?s)xmlns:?\\w*=['\"].*?['\"]", "");
      s = s.replaceAll("(?s)\\w*:schemaLocation=['\"].*?['\"]", "");
      return s;
    }
   
    /**
     * 解析attributes为hashMap
     * @param attributes 格式: name='badqiu' sex='F'
     * @return
     */
    public static LinkedHashMap<String, String> parse2Attributes(String attributes) {
      LinkedHashMap result = new LinkedHashMap();
        Pattern p = Pattern.compile("(\\w+?)=['\"](.*?)['\"]");
        Matcher m = p.matcher(attributes);
        while(m.find()) {
            result.put(m.group(1),StringHelper.unescapeXml(m.group(2)));
        }
        return result;
    }
   
    public static void main(String[] args) throws FileNotFoundException, SAXException, IOException {
        String file = "D:/dev/workspaces/alipay/ali-generator/generator/src/table_test.xml";
        NodeData nd = new XMLHelper().parseXML(new FileInputStream(new File(file)));
       
        LinkedHashMap table = nd.attributes;
        List columns = nd.childs;
        System.out.println(table);
        System.out.println(columns);
//        System.out.println(nd);
    }

}
TOP

Related Classes of cn.org.rapid_framework.generator.util.XMLHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.