public XmlScript parse(String script) {
    ScriptNode node = null;
    ScriptNode next = null;
    int idx = 0;
    int gt = 0;
    int dot = 0;
    while (gt >= 0 || dot >= 0) {
      ScriptNode current = new ScriptNode();
      gt = script.indexOf(">", idx);
      dot = script.indexOf(".", idx);
      int min = 0;
      if (gt >= 0 && dot >= 0) {
        min = Math.min(gt, dot);
      } else {
        min = Math.max(gt, dot);
      }
      int subIdx = script.indexOf("[", idx);
      //			if(min>idx){
      if (subIdx > 0) {
        String str = null;
        if (min > idx) {
          str = script.substring(idx, min);
        } else {
          str = script.substring(idx);
        }

        if (StringUtils.isNotBlank(str)) {
          // >{}>  >{}.
          current.setScript(str);
          int idxStart = str.indexOf("[", 0);
          int idxEnd = str.indexOf("]", 0);
          if (idxStart < idxEnd && idxStart > 0) {
            String type = str.substring(0, idxStart);
            if (StringUtils.isNotBlank(type)) {
              current.setType(type);
            } else {
              throw new RuntimeException("invalid script:" + script);
            }
            // a[0]   []
            String idxScript = str.substring(idxStart + 1, idxEnd);
            NodeIndex nodeIndex = this.parseScriptIndex(idxScript);
            current.setIndexes(nodeIndex);

            // a[0]{}  {} attribute条件提取
            int attStart = str.indexOf("{", idxEnd);
            int attEnd = str.indexOf("}", idxEnd);
            int conFrom = idxEnd;

            if (attEnd > attStart && attStart > 0) {
              conFrom = attEnd;
              String attScript = str.substring(attStart + 1, attEnd);
              if (StringUtils.isNotBlank(attScript)) {
                Map<String, String> attr = parser.parseParams(attScript);
                current.setAttributes(attr);
              } else {
                current.setAttributes(new HashMap<String, String>());
              }
              // a[0]{}()  ()//()相对条件提取
              int conStart = str.indexOf("(", attEnd);
              int conEnd = str.indexOf(")", attEnd);

              if (conStart > 0 && conEnd > 0) {
                conFrom = conEnd;
                current.setConditions(new ArrayList<ScriptNodeCondition>());
                String subConditions = str.substring(conStart + 1, conEnd);
                if (StringUtils.isNotBlank(str)) {
                  String[] conditions = subConditions.split(",");
                  for (String condition : conditions) {
                    if (StringUtils.isNotBlank(condition)) {
                      ScriptNodeCondition scriptNodeCondition = this.parseCondition(condition);
                      current.getConditions().add(scriptNodeCondition);
                    }
                  }
                } else {
                  current.setConditions(new ArrayList<ScriptNodeCondition>());
                }
              } else if (conStart < 0 && conEnd < 0) {
                current.setConditions(new ArrayList<ScriptNodeCondition>());
              } else {
                throw new RuntimeException("invalid script:" + script);
              }
            } else {
              if (attStart < 0 && attEnd < 0) {
                current.setAttributes(new HashMap<String, String>());
              } else {
                throw new RuntimeException("invalid script:" + script);
              }
            }
            // 可能存在condition的条件下
            if (conFrom > 0 && conFrom < str.length() - 1) {
              int conIdx = str.indexOf("?", conFrom);
              if (conIdx > 0) {
                String content = str.substring(conIdx + 1).trim();
                int conStart = content.indexOf("\"", 0);
                int conEnd = content.lastIndexOf("\"");
                if (conStart < conEnd && conStart >= 0) {
                  String operate = null;
                  if (conStart > 0) {
                    operate = content.substring(0, conStart);
                  } else {
                    operate = "contains";
                  }
                  String con = content.substring(conStart + 1, conEnd);
                  current.setContent(con);
                  current.setOperate(operate);
                } else {
                  throw new RuntimeException("invalid condition:" + content);
                }
              }
            }
          } else {
            throw new RuntimeException("invalid script:" + script);
          }
        } else {
          throw new RuntimeException("invalid script:" + script);
        }

        if (node == null) {
          node = current;
          next = node;
        } else {
          next.setNext(current);
          next = current;
          current = null;
        }
        if (min >= 0) {
          idx = min + 1;
        } else {
          break;
        }
      } else {
        // a[0].href  href
        String str = script.substring(idx);
        if (StringUtils.isNotBlank(str)) {
          current.setScript(str);
          current.setValue(true);
        } else {
          throw new RuntimeException("invalid script:" + script);
        }
        if (node == null) {
          node = current;
          next = node;
        } else {
          next.setNext(current);
          next = current;
          current = null;
        }
        break;
      }
    }
    return new XmlScript(script, node);
  }
  /**
   * span[0]{class=\"\"}?\"\"
   *
   * @param condition
   * @return
   */
  private ScriptNodeCondition parseCondition(String condition) {
    ScriptNodeCondition nodeCondition = new ScriptNodeCondition();
    nodeCondition.setScript(condition);
    int start = condition.indexOf("[");
    int end = condition.indexOf("]");
    if (start > 0 && end > 0) {
      String type = condition.substring(0, start);
      nodeCondition.setType(type);
      // []
      String indexSrc = condition.substring(start + 1, end);
      NodeIndex index = this.parseScriptIndex(indexSrc);
      nodeCondition.setIndex(index);

      // {}
      int attStart = condition.indexOf("{", end);
      int attEnd = condition.indexOf("}", end);
      if (attStart > 0 && attEnd > attStart) {
        String attScript = condition.substring(attStart + 1, attEnd);
        if (StringUtils.isNotBlank(attScript)) {
          Map<String, String> attr = parser.parseParams(attScript);
          nodeCondition.setAttributes(attr);
        } else {
          nodeCondition.setAttributes(new HashMap<String, String>());
        }
      } else {
        if (attStart < 0 && attEnd < 0) {
          nodeCondition.setAttributes(new HashMap<String, String>());
        } else {
          throw new RuntimeException("invalid condition:" + condition);
        }
      }
      int contentIdx = -1;
      if (attEnd > 0) {
        contentIdx = condition.indexOf("?", attEnd);
      } else {
        contentIdx = condition.indexOf("?", end);
      }

      if (contentIdx > 0) {
        String content = condition.substring(contentIdx + 1).trim();
        int conStart = content.indexOf("\"", 0);
        int conEnd = content.lastIndexOf("\"");
        if (conStart < conEnd && conStart >= 0) {
          String operate = null;
          if (conStart > 0) {
            operate = content.substring(0, conStart);
          } else {
            operate = "contains";
          }
          String con = content.substring(conStart + 1, conEnd);
          nodeCondition.setContent(con);
          nodeCondition.setOperate(operate);
        } else {
          throw new RuntimeException("invalid condition:" + content);
        }
      }
    } else {
      throw new RuntimeException("invalid condition:" + condition);
    }
    return nodeCondition;
  }