一位朋友曾叫我幫忙改個工具,可以指定要Search什麼Tag,這的確是很好的Regex題目,而且可以用Java Script達成,但因為涉及File IO需要用IE,以下的Sample中最重要的function是SearchTag,這Function還是有Bug存在,容後解說:
<html>
<head>
<title>xml驗證與搜尋程式</title>
</head>
<body>
<script language="javaScript">
function checkxml(form){
   if(form.target.value==''){
      alert('請點選[瀏覽]按鈕,選擇驗證檔案!')
      return;
   }
   var dom=new ActiveXObject("Microsoft.XMLDOM");
   dom.async='false';
   var str='';
   if(!dom.load(form.target.value)){
  str='<font color="red">失敗,xml驗證檔案:'+form.target.value;
  str=str+'<br>錯誤代碼:'+dom.parseError.errorCode;
  str=str+'<br>錯誤理由:'+dom.parseError.reason;
  str=str+'<br>錯誤行數:'+dom.parseError.line;
  str=str+'<br>錯誤位置:'+dom.parseError.linepos;    
  str=str+'<br>錯誤細節:'+dom.parseError.srcText.replace("","")+'\n</font>';
   }else{
       str='<font color="green">成功,xml驗證檔案:'+document.xmlvalidate.target.value+'</font>';  
   }
   testResult.innerHTML=str;
}
function openxmlfile(form){
   if(form.target.value==''){
      alert('請點選[瀏覽]按鈕,選擇驗證檔案!')
      return;
   }
   var maxh=screen.availHeight-60 ;
   var maxw=screen.availWidth-10 ;
   var strFratures="left=0,top=0,scrollbars=1,status=1";
   strFratures+=",height=" + maxh;
   strFratures+=",width=" + maxw;
   wid=window.open(form.target.value,'openxmlfile',strFratures);
}
function searchTag(form) {
 var fso = new ActiveXObject("Scripting.FileSystemObject");
 var txtfile = form.target.value;
 var re = /\\/g;
 txtfile = txtfile.replace(re, "
\\\\");  // 把\換成\\
 var ts = fso.OpenTextFile(txtfile, 1); // for reading
 var cont;
 while (!ts.AtEndOfStream) cont += ts.ReadLine();  // 因為FileSystemObject是逐行讀檔,要全合併一個大字串
 ts.Close();
 var re_str = "\<" + form.tag.value + "( .*?)?\>.*?\</" + form.tag.value + "\>|\<" + form.tag.value + "( .*?)?/\>";
 var p = new RegExp(re_str, "g");
 var result = cont.match(p);
 var i;
 if (result != null) {
  form.cont.value = "";
  for (i=0; i<result.length; i++) {
   form.cont.value += result[i] + "\n\n";
  }
 } else {
  alert("找不到該標籤:" + form.tag.value);
 }
}
</script>
<center>
<form name="xmlvalidate">
   <table BORDER="0" width="100%" style="font-size:14pt;">
      <th style="font-size:18pt;  align="center" 
colspan="2">Xml檔案驗證與搜尋<hr><th>
      <tr >
         <td align="right"  width="30%">
            請輸入欲驗證檔案:
         </td>
         <td width="70%">
            <input type="file" name="target" size="60">
         </td>
      </tr>
      <tr>
         <td  align="center" colspan="2">
            <input type="button" value="驗證" onclick="checkxml(this.form)">
            <input type="button" value="查看驗證檔案內容" onclick="openxmlfile(this.form)">
         </td>
      </tr>
   <tr>
         <td align="right">
   請輸入欲搜尋的標籤:
         </td>
         <td>
            <input type="text" name="tag">
            <input type="button" value="搜尋" onclick="searchTag(this.form)">
            <input type="button" value="清除" onclick="form.cont.value=''">
         </td>
      </tr>
      <tr style="background-color:#F5DEB3;">
         <td align="right" valign="top">驗證結果:</td>
         <td id="testResult"> </td>
      </tr>
      <tr style="display:none;">
   <td  align="center" colspan="2">
   <INPUT type="text" NAME="RESULTS" size="120">
   </td>
   </tr>
   <tr style="background-color:#F5DEB3;">
   <td  align="center" colspan="2">
   <TEXTAREA NAME="cont" ROWS="25" COLS="110"></TEXTAREA>
   </td>
   </tr>
</form>
</body>
</html>
 
上述標紅底字是搜尋標籤的核心,考慮到以下的情況:
<label>....</label>
<label attr="xxx">...</label>
<label/>
但這段Regex的Bug是對下面的情況沒輒:
<label><label>....</label><test>...</testl></label> 只比對到粗體字的部份,會先找到第一個</label>
<label attr att1=error>...</label>  對attribute沒有比對為attr="..."形式
但做程式有兩種,一是求完美,上述的Regex就不合格;第二是省成本,微軟的Microsoft.XMLDOM的ActiveObject就可以幫我們做上述的驗證,不必再費時間設計更完美的Regex。
arrow
arrow
    全站熱搜

    Jemmy 發表在 痞客邦 留言(0) 人氣()