使用XML+XSLT实现业务表单

http://www.cnblogs.com/lijun4017/archive/2008/04/28/1175323.html

其实这是我的一个两年前的项目中用到的东西,今天刚好翻以前的代码,看到,觉得也是自己想出来的东西,写写也无妨,哪怕是为了填充我空虚的blog。这个是一个智能客户端,但是里面涉及的表单非常之多,统计一下,有200个张。本来也不是问题,用FORM一个一个画也能够画出来,但是这样有几个缺点,一方面导致智能客户端的dll变的比较大,每次更新的时候,都要下载整个dll;一方面分工不好分,原来那个公司那时候只有我用过winform,老板就把这个任务分配给我了。但是我一个人,要做那么多的表单,而且在比较短的时间内,也不是说不可能,太累了。我想想看能不能有其他方法。

当时XFORM的概念相当热,我也看了一些资料,觉得还是不太成熟,没有敢用。

后来看了微软office2007中的infopath,感觉功能非常强,它可以实现用infopath设计表单,然后用表单控件把表单嵌入到winform中去,并且可以实现表单中的数据加载和保存功能。但是唯一的遗憾就是如果要使用它,就必须要客户机器上安装office2007,这样就不太现实了。

最后来想到的是用xml+xslt是动态生成静态页面,然后把静态页面嵌入在winform的浏览器控件里面,并且屏蔽一些浏览器控件的一些属性,看起来就和winform设计的表单差不多了。这样就方便多了,我可以叫美工帮我设计表单,叫其他的asp.net的程序员帮忙做XML和XSLT以及里面的javascript脚本。后来的项目进展说明了,这种方式真的大大的提高了工作效率,也让我轻松了不少,嘿嘿,又偷懒了。


下面我说说具体的过程吧。
1。首先我在设计表的时候,把整个表单的内容设计成XML类型的字段,当然,其他需要搜索的字段还是要单独建字段,并且保存xslt文件的版本号。
2。设计表单的XML结构,下面是示例。

<? xml version = " 1.0 "  encoding = " utf-8 "   ?>
<!-- 现场会议记录 -->
< meetnote >
  
< enterprise ></ enterprise >
  
<!-- 会议名称 -->
  
< meets >
    
< meet >
      
< name > meet1 </ name >
      
< checked > false </ checked >
    
</ meet >
    
< meet >
      
< name > meet2 </ name >
      
< checked > false </ checked >
    
</ meet >
    
< meet >
      
< name > meet3 </ name >
      
< checked > false </ checked >
    
</ meet >
  
</ meets >
  
< compere  />
  
< recorder  />
  
< address  />
  
< meetdate  />
  
< content  />
</ meetnote >


3.设计表单的XSLT文件,下面是示例。

<? xml version = " 1.0 "  encoding = " utf-8 " ?>
< xsl:stylesheet xmlns:xsl = " http://www.w3.org/1999/XSL/Transform "  
                xmlns:msxsl
= " urn:schemas-microsoft-com:xslt "                  
                version
= " 1.0 "   >
  
< xsl:template match = " / " >
    
< html >
      
< head >
        
< link href = " ../css/xmltable.css "  rel = " stylesheet "  type = " text/css "   />
        
< script language = " javascript " >
          
// 使用客户端日期JS脚本初始化

          var date 
=   new  Date();
          var   Fun_Year 
=  date.getYear();
          var   Fun_Month 
=  date.getMonth() + 1 ;
          var   Fun_Day 
=  date.getDate();
        
</ script >
        
< script language = " javascript "  src = " ../javascript/calendar.js " ></ script >
        
< script language = " javascript "  src = " ../javascript/check.js " ></ script >
        
< script language = " javascript "  src = " ../javascript/common.js " ></ script >
        
< script language = " javascript " >
          function validate()
          
{
          var errorinfo
="";
          
if(clearSpace(txtcompere.value)=="")
          
{
          errorinfo 
+= "主持人为空\n";
          }

          
if(clearSpace(txtaddress.value)=="")
          
{
          errorinfo
+= "会议地点为空\n";
          }

          
if(clearSpace(txtrecorder.value)=="")
          
{
          errorinfo
+="记录人为空\n";
          }

          
if(clearSpace(txtmeetdate.value)=="")
          
{
          errorinfo 
+= "会议时间为空\n";
          }

          
if(clearSpace(txtcontent.innerText)=="")
          
{
          errorinfo
+= "会议内容为空\n";
          }

          
//会议名称
          if(txtmeet1.checked != true &amp;&amp; txtmeet2.checked != true &amp;&amp; txtmeet3.checked != true)
          
{
          errorinfo
+= "请选择会议名称\n";
          }

          
if(errorinfo=="")
          
{
          
return true;
          }

          
else
          
{
          window.external.ShowErrorMessage(errorinfo);
          
return false;
          }


          }

          
// 数据保存
          function savetoxml()
          
{
          var doc 
= new ActiveXObject("Msxml2.DOMDocument");
          doc.async 
= false;
          
//调用c#方法获取xml文件路径
          var xmlfilepath = window.external.GetXMLPathForJava();
          doc.load(xmlfilepath);

          
//会议名称
          doc.selectNodes("meetnote/meets/meet")[0].lastChild.text=(txtmeet1.checked==0)?'false':'true';
          doc.selectNodes(
"meetnote/meets/meet")[1].lastChild.text=(txtmeet2.checked==0)?'false':'true';
          doc.selectNodes(
"meetnote/meets/meet")[2].lastChild.text=(txtmeet3.checked==0)?'false':'true';

          doc.selectSingleNode(
"meetnote/compere").text=txtcompere.value;
          doc.selectSingleNode(
"meetnote/recorder").text=txtrecorder.value;
          doc.selectSingleNode(
"meetnote/address").text=txtaddress.value;
          doc.selectSingleNode(
"meetnote/meetdate").text=txtmeetdate.value;
          doc.selectSingleNode(
"meetnote/content").text=txtcontent.innerText;

          
//调用c#方法保存xml文件
          var examfiletype = window.external.GetExamFileType();
          var examfilename 
= window.external.GetExamFileName();
          window.external.Save(doc.xml,examfiletype,examfilename);
          
return true;
          }

        
</ script >
        
</ head >
      
< body >
        
< xsl:apply - templates />
      
</ body >
    
</ html >
  
</ xsl:template >

  
< xsl:template match = " meetnote " >
   
    
< table border = " 1 "  align = " center "  cellPadding = " 0 "  cellSpacing = " 0 "    class = " table " >

      
< tr >
        
< td   class = " td1 "   colspan = " 4 " >
          
< div align = " center "   class = " title " > 现场审核会议记录 </ div >
        
</ td >
      
</ tr >
      
< tr >
        
< td  class = " td2 " >
          
< span > 受审核方: </ span >

          
< xsl:value - of select = " enterprise "   />

        
</ td >
      
</ tr >
      
< tr >
        
< td  class = " td2 " >
          
< span > 会议名称: </ span >
          
< xsl:apply - templates select = " meets/meet " />
        
</ td >
      
</ tr >
      
< tr >
        
< td  class = " td2 " >
          
< span > 主 持 人: </ span >
          
< input style = " WIDTH: 150px;  "  type = " text "  name = " txtcompere " >
            
< xsl:attribute name = " value " >
              
< xsl:value - of select = " compere "   />
            
</ xsl:attribute >
          
</ input >
          
< span > 会议地点: </ span >
          
< input style = " WIDTH: 200px;  "  type = " text "  name = " txtaddress " >
            
< xsl:attribute name = " value " >
              
< xsl:value - of select = " address "   />
            
</ xsl:attribute >
          
</ input >
        
</ td >
      
</ tr >
      
< tr >
        
< td  class = " td2 " >
          
< span > 记 录 人: </ span >
          
< input style = " WIDTH: 150px;  "  type = " text "  name = " txtrecorder " >
            
< xsl:attribute name = " value " >
              
< xsl:value - of select = " recorder "   />
            
</ xsl:attribute >
          
</ input >
          
< span > 会议时间: </ span >
          
< input style = " WIDTH: 100px;  "  type = " text "  name = " txtmeetdate "  onfocus = " calendar(); "  id = " txtmeetdate " >
            
< xsl:attribute name = " value " >
              
< xsl:value - of select = " meetdate "   />
            
</ xsl:attribute >
          
</ input >
        
</ td >
      
</ tr >
      
< tr >
        
< td   valign = " top "   class = " td2 " >
          
< span > 会议内容: </ span >
          
< br />
          
< textarea style = " WIDTH: 100%;HEIGHT:150px  "  type = " text "  name = " txtcontent " >
              
< xsl:value - of select = " content "   />
          
</ textarea >
        
</ td >
      
</ tr >
    
</ table >
  
</ xsl:template >
  
<!-- 会议名称 -->
  
< xsl:template match = " meets/meet " >
    
< xsl: if  test = " name='meet1' " >
      
< input type = " checkbox "  name = " txtmeet1 "  id = " txtmeet1 "  onclick = " radiobutton(this,'txtmeet') " >
        
< xsl: if  test = " checked='true' " >
          
< xsl:attribute name = " checked " >
            
checked
          
</ xsl:attribute >
        
</ xsl: if >
      
</ input >
      
< span > 首次会议 </ span >
    
</ xsl: if >
    
< xsl: if  test = " name='meet2' " >
      
< input type = " checkbox "  name = " txtmeet2 "  id = " txtmeet2 "  onclick = " radiobutton(this,'txtmeet') " >
        
< xsl: if  test = " checked='true' " >
          
< xsl:attribute name = " checked " >
            
checked
          
</ xsl:attribute >
        
</ xsl: if >
      
</ input >
      
< span > 沟通会议 </ span >
    
</ xsl: if >
    
< xsl: if  test = " name='meet3' " >
      
< input type = " checkbox "  name = " txtmeet3 "  id = " txtmeet3 "  onclick = " radiobutton(this,'txtmeet') " >
        
< xsl: if  test = " checked='true' " >
          
< xsl:attribute name = " checked " >
            
checked
          
</ xsl:attribute >
        
</ xsl: if >
      
</ input >
      
< span > 末次会议 </ span >
    
</ xsl: if >
  
</ xsl:template >
</ xsl:stylesheet >



4。在XSLT文件中加入JS脚本,用户验证用户输入,收集表单数据,加载表单数据等。(这里涉及到JS代码和浏览器控件所在的winform窗体的代码的相互调用。)
1)首先把winform窗体的类加上这个属性[ComVisible(true)]

2) 在winform窗体里面写上public的方法

        //取得xml文件路径(供javascript调用)
        public string GetXMLPathForJava()
        {          
            return tempxmlfilepath;
        }
3)在XSLT文件里面的JS代码中调用这个方法
  //调用c#方法获取xml文件路径
         var xmlfilepath = window.external.GetXMLPathForJava();
4)在XSLT文件中定义JS方法
         //数据保存
          function savetoxml()
          {
         } 
5)在winform窗体中调用JS方法
 //调用JS方法
 Object result = webBrowser1.Document.InvokeScript("savetoxml");

5.在显示页面的时候,我先使用下面的代码把XSLT和XML转换成HTML文件,存放在临时文件夹中,然后把浏览器控件的URL指向它。

  XslCompiledTransform transForm  =   new  XslCompiledTransform();
            
string  xsltemplatepath  =  TemplateHelper.GetFactoryFormXSLTemplatePath(m_FileType, m_DataRow.xsl_version);

            
try
            
{
                transForm.Load(xsltemplatepath);
                transForm.Transform(tempxmlfilepath, temphtmlfilepath);
            }

            
catch (Exception ex)
            
{
                LogError.Write(ex.Message 
+ "\n" + ex.StackTrace);
                MessageBox.Show(
"模板文件加载出错!");
                
this.Close();
                
return;
            }

            webBrowser1.Navigate(temphtmlfilepath);


6。在用户点击保存的时候,我通过XSLT中定义的JS代码,直接把用户保存的数据以XML的方式返回给winform的代码,然后保存到数据库中去。

 Object validateresult  =  webBrowser1.Document.InvokeScript( " validate " );
            
if  (Convert.ToBoolean(validateresult)  ==   true )
            
{
                Object result 
= webBrowser1.Document.InvokeScript("savetoxml");
                
if (Convert.ToBoolean(result) == true)
                
{
                    
this.Close();
                }

                
else
                
{
                    MessageBox.Show(
"保存出错""提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    
this.DialogResult = DialogResult.None;
                }

            }

            
else
            
{
                
this.DialogResult = DialogResult.None;
            }


7。删除刚才产生的临时文件。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值