w3cdomsql使用说明:
 1:只能解析xml文件
 2:只能解析标签cfj、model、sql、java、js 五个标签(所有标签都是自定义,可以自行更改)
 标签说明:cfj标签相当于mybatis中的mapping
          model为模块 必须配置属性id
          sql为对应的与数据库交互的sql配置  必须配置id
          java表示配置的字符串将以java进行编译并返回结果(注:java 里面不能有反斜杠转义字符,循环最好只用while for循环只支持for in ,
                                                          也不支持++,+=,-+,--,等逻辑运算,其他海待测试)
          js表示配置的字符串将以javasrcipt进行编译运算并返回结果  3.参数传递:参数传递方式:#{wyid}且只支持这种方式     
4.优缺点:缺点1.由于是动态解析因此如果数据量大解析较慢,
                        2.java代码逻辑支持率不高尽量不要在内部写逻辑,
                        3.js代码逻辑支持率较高尽量采用js代码
                 优点:1.项目不用搭建mybatis框架
                            2.更改xml文件后不需要重启服务器,连前端都不需要重新刷新
                            3.所有东西都是自行定义,好理解便于维护,并且可适用于所有框架以及模块。   
<?xml version="1.0" encoding="UTF-8" ?>
         <!--xml文件示例 java  循环只支持while循环 for循环支持率不高 慎用-->
 <cfj>
     <model id="fbdw">
         <sql id="fbdw_info">
         select * from fbdw_info where 1=1
         <java>
             if(zjsl==3){
              sql.append("and zjsl=3 and wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }");
             }else{
             sql.append("and zjsl!=3 wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }");
             }
         </java>
             <js>
                 if(zjsl==3){
                  sql+="and zjsl='3' and wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }";
                 }else{
                   sql+="and zjsl!='3' and wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }";
                 }
             </js>
         </sql>
     </model>
 </cfj>
 效果
package cfjsf.util.w3cdom;
import org.apache.commons.jexl2.Expression;
 import org.apache.commons.jexl2.JexlContext;
 import org.apache.commons.jexl2.JexlEngine;
 import org.apache.commons.jexl2.MapContext;
 import org.w3c.dom.*;import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import java.io.File;
 import java.util.Map;/**
  * Created by 常发均 on 2019/8/7.
  * xml文件动态生成sql解析工具类(脱离于mabatis框架,更改xml文件后不需要重启服务器,并且支持内部java代码以及js代码以及逻辑运算)
  */
 public class XmlDynamicParseToSql {
    public static String xmlSql(File file,String modelId,String sqlId,Map<String,Object> params) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(file);
        //获得根元素结点
        Element root = doc.getDocumentElement();
        return parseGcgs(root,modelId,sqlId,params);
    }
    private static String parseGcgs(Element element,String modelId,String sqlId,Map<String,Object> params) throws Exception {
        StringBuffer dtSql=new StringBuffer("");
        parseElementGcgs(element, modelId,sqlId,dtSql,params);
        return dtSql.toString();
    }
     private static void parseElementGcgs(Element element,String modelId,String sqlId,StringBuffer dtSql,Map<String,Object> params) throws Exception {
         String tagName = element.getNodeName();
         if(!(tagName.equals("cfj")||tagName.equals("java")||tagName.equals("js")||tagName.equals("model")||tagName.equals("sql"))){
             throw new Exception("this targetName count no found!");
         }
         boolean flag=true;
         if(tagName.equals("model")||tagName.equals("sql")){
             flag=false;
         }
         NodeList children = element.getChildNodes();
         //element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断
         NamedNodeMap map = element.getAttributes();
         //如果该元素存在属性
         /*
         * 后面已经有判断 主要是担心认为操作失误 且第一个节点就为目标节点 判断不到
         * 因此再次采用多重判断
         * */
         if(null != map)
         {
             for(int i = 0; i < map.getLength(); i++)
             {
                 //获得该元素的每一个属性
                 Attr attr = (Attr)map.item(i);
                 String attrName = attr.getName();
                 String attrValue = attr.getValue();
                 if(attrName.equals("id")){
                     if(tagName.equals("model")&&attrValue.equals(modelId)){
                         flag=true;
                     }else if(tagName.equals("sql")&&attrValue.equals(sqlId)){
                         flag=true;
                     }
                 }
             }
         }
        if(flag){
            for(int i = 0; i < children.getLength(); i++)
            {
                Node node = children.item(i);
                int a=0;//默认a等于0 表示节点名称不为model与sql的节点需继续所有节点递归 a等于1表示还未找到目标节点需跳出循环继续寻找 a等于2 表示已找到目标节点
               /*
                * 判断是否找到当前所需节点 找到就结束循环
                * */
                if(node.getNodeName().equals("model")){
                    if(isMbNode((Element) node,"model",modelId)){
                        a=2;
                    }else{
                        a=1;
                        continue;
                    }
                }  else if(node.getNodeName().equals("sql")){
                    if(isMbNode((Element) node,"sql",sqlId)){
                        a=2;
                    }else{
                        a=1;
                        continue;
                    }
                }
                //获得结点的类型
                short nodeType = node.getNodeType();
                if(nodeType == Node.ELEMENT_NODE)
                {
                    //递归出口
                    /*
                    * sql节点下只能含有java与js节点  方便解析
                    *
                    * */
                    if(tagName.equals("sql")){
                        if(node.getNodeName().equals("java")||node.getNodeName().equals("js")){
                            //是元素,继续递归
                            parseElementGcgs((Element)node,modelId,sqlId,dtSql,params);
                        }else{
                            throw new Exception("sql标签中只能含有java或者js标签!");
                        }
                    }
                    else{
                        parseElementGcgs((Element)node,modelId,sqlId,dtSql,params);
                    }
                }
                else if(nodeType == Node.TEXT_NODE)
                {
                    //递归出口
                    if(tagName.equals("sql")){
                        dtSql.append(node.getNodeValue().trim());
                        dtSql.append(" ");
                    }
                    else if(tagName.equals("java")){
                        dtSql.append(dtjxJava(node.getNodeValue().trim(),params));
                        dtSql.append(" ");
                    }
                    else if(tagName.equals("js")){
                        dtSql.append(dtjxJs(node.getNodeValue().trim(), params));
                        dtSql.append(" ");
                    }
                    /*
                    * 替换掉所有的参数 参数方式采用#{}
                    * */
                    if(dtSql.toString().indexOf("#")>-1){
                        String[] arr=dtSql.toString().split("\\#");
                        String str="";
                        int length=dtSql.toString().length();
                        for(int j=arr.length-1;j>=1;j--){
                            length=length-arr[j].length()-1;
                            if(arr[j].indexOf("{")>-1&&arr[j].indexOf("}")>arr[j].indexOf("{")+1){
                                str=arr[j].substring(arr[j].indexOf("{")+1,arr[j].indexOf("}"));
                                if(params.containsKey(str.trim())){
                                    dtSql.replace(length,length+arr[j].indexOf("}")+2,"'"+params.get(str.trim()).toString()+"'");
                                }else{
                                    throw new Exception("找不到参数"+str.trim()+"!");
                                }
                            }
                        }
                    }
                }
                else if(nodeType == Node.COMMENT_NODE)
                {
                    Comment comment = (Comment)node;
                    //注释内容
                    String data = comment.getData();
                }
                if(a==2){
                    break;
                }
            }
        }
     }
     /*
     * 将字符串通过java进行动态编译并返回计算结果
     * 采用jexl进行解析
     * */
     private static String dtjxJava(String javaStr,Map<String,Object> params){
         JexlEngine jexl=new JexlEngine();
         JexlContext jc = new MapContext();
         for(String key:params.keySet()){
             jc.set(key,params.get(key));
         }
         jc.set("sql",new StringBuffer(""));
         Expression e = jexl.createExpression(javaStr);
         if(null==e.evaluate(jc)){
             return "";
         }else{
             return jc.get("sql").toString().trim();
         }
     }
     /*
     * 将字符串通过javasricpt进行动态编译并返回计算结果
     * */
    private static String dtjxJs(String jsSr,Map<String,Object> params){
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        for(String key:params.keySet()){
            engine.put(key, params.get(key));
        }
        engine.put("sql","");
        try {
            engine.eval(jsSr);
            return engine.get("sql").toString().trim();
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return "";
    }
      /*
     * 判断id是否相同
     * */
     private static boolean isMbNode(Element node,String nodeName,String nodeValue) throws Exception {
         if(node.getNodeName().equals(nodeName)){
             NamedNodeMap idNodeMap = node.getAttributes();
             if(null!=idNodeMap){
                 try {
                     Attr attr=(Attr)idNodeMap.getNamedItem("id");
                     if(attr.getValue().equals(nodeValue)){
                       return true;
                     }
                 }catch (Exception e){
                     throw new Exception("请对该节点配置id属性!");
                 }
             }else{
                 throw new Exception("请对该节点配置id属性!");
             }
         }
        return false;
     }
  }