[转载]如何使用CodeSmith批量生成代码

mikel阅读(1131)

[转载]如何使用CodeSmith批量生成代码(原创) – 批发の上帝ぐ – 博客园.

下面我会一步步的解释如何用CodeSmith实现预期的结果的,事先声明一下,在此只做一个简单的Demo,并不详细 的讲解CodeSmith各个强大的功能,有兴趣的朋友可以打开CodeSmith的帮助文档了解.我只做个抛石引玉,希望能激起大家更多思想的火花~

先看看CodeSmith的工作原理:

简单的说:CodeSmith首先会去数据库获取数据库的结构,如各个表的名称,表的字段,表间的关系等等,之后再根据 用户自定义好的模板文件,用数据库结构中的关键字替代模板的动态变量,最终输出并保存为我们需要的目标文件.好,原理清楚了,就开始实践吧:

1. 运行CodeSmith,可以看到如下界面:

2. CodeSmith是创建模板的地方,首先当然是创建一个模板啦,点击工具栏最左边的New DocumentC# Template,如图所示:

3. 点击运行按钮,运行结果如下:

好,我们来分析为什么会得到这样的运行结果吧,点击运行窗口左下角的Template按钮返回模板设计窗口,可以发现, 只要是没有被<%%>或者<scriptrunat=”template”></script>包 含的文字均被直接输出了,这些以后就要被换成我们分层架构中一些一成不变的模板代码:

4. 好了,简单了解啦一些CodeSmith的代码结构,下面就开始用它来生成我们的分层代码吧,在此我就不介绍分层架构的概念了,不然就偏离主题了. 为了能更简单明了的说明,我们在此就只用CodeSmith生成分层架构的实体层吧.先看看如果我们不使用CodeSmith需要手动敲出哪些代码:

Major.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Entity { public partial class Major { public Int32 MajorID{ get;set; } public String Name{ get;set; } public String Remark{ get;set; } } }

Student.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Entity { public partial class Student { public String StudentID{ get;set; } public Int32 MajorID{ get;set; } public String Name{ get;set; } public Boolean Sex{ get;set; } public Int32 Age{ get;set; } public String Remark{ get;set; } } }

我将两个文件中重复的代码使用黄色背景色加深了,我们可以发现,如果每个表都要通过手动创建,那么将有大量的代码(黄色 背景)需要复制粘贴操作,这些操作是繁琐而没有任何意义的.因此,我们会希望将黄色背景部分的代码做成模板,而其他变化的代码由数据库的结构动态生成,如 此一来,我们就不用再为这些烦人的复制粘贴操作懊恼了.

5. 那么就开始我们的实践吧,就在刚刚创建好的文件开始吧,先随意保存到一个目录下,命名为test.cst,接 着删除多余的代码,只保留第一行,该行表明我们的模板使用何种语言,这里我们使用C#.

<%@ CodeTemplateLanguage="C#" TargetLanguage="Text" Src="" Inherits=""Debug="False" CompilerVersion="v3.5"Description="Template description here." %>

6. 参照CodeSmith的工作原理,我们首先要为CodeSmith提供一个数据库,要怎么使它和SQL Server 2005关联起来呢?只要加上下面的代码就行了:

<%-- 加载访问数据库的组件SchemaExplorer,并声明其使用的命名空间 --%> <%@ AssemblyName="SchemaExplorer" %> <%@ ImportNamespace="SchemaExplorer" %> <%-- 数据库 --%> <%@ PropertyName="SourceDatabase"DeepLoad="True" Optional="False" Category="01. GettingStarted - Required" Description="Database that the tables views, and storedprocedures should be based on. IMPORTANT!!! If SourceTables and SourceViews areleft blank, the Entire Database will then be generated." %>

7. 好了,有了数据库连接,接着还需要一个模板,为了便于管理,我们新建一个文件用于设计模板,FileNewBlank  Template,并添加如下代码,最好保存到test.cst所在的文件夹内,命名为Entity.cst:

<%@ CodeTemplateInherits="CodeTemplate"TargetLanguage="Text" Description="NetTiers main template."Debug="True" ResponseEncoding="UTF-8"%> <%@ AssemblyName="SchemaExplorer" %> <%@ ImportNamespace="SchemaExplorer" %> <%-- 要打印的表 --%> <%@ PropertyName="Table" DeepLoad="True"Optional="False" Category="01. Getting Started - Required"Description="Database that the tables views, and stored procedures shouldbe based on. IMPORTANT!!! If SourceTables and SourceViews are left blank, theEntire Database will then be generated." %>

接着继续添加如下代码:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Entity { public partial class <%= Table.Name%> { <% foreach(ColumnSchema col inTable.Columns){ %> public <%= col.DataType %> <%=col.Name %>{ get;set; } <% } %> } }

<%=Table.Name%> 表示在此处输出表的名称

<%foreach(ColumnSchema col in Table.Columns){ %> <% } %> 为循环语句,在{}循环输出列信息.

<%=col.DataType %> 表示在此处输出列的类型

<%=col.Name %> 表示在此处输出列的名称

如图所示:

8. 模板创建好后,要在test.cst文件中注册一下,不然人家怎么知道有你这么一个模板存在呀,在 test.cst文件继续输入如下代码:

<%-- 注册实体层Entity模板 --%> <%@ RegisterName="EntityTemplate" Template=" Entity.cst"MergeProperties="Flase" ExcludeProperties=""%>

9. 好了,模板注册好了,根据CodeSmith工作原理,我们要结合模板和数据库结构来批量生成代码啦,但是我们生 成的目标文件要输出到哪里呢?这时我们会需要一个用户自定义属性,用于设置目标文件的输出目录,在test.cst文件的末尾输入如下代码:

代码

<script runat="template"> //解决方案输出路径 private string Directory = String.Empty; [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))] [Optional, NotChecked] [DefaultValue("")] public string OutputDirectory { get { return Directory; } set { if (value.EndsWith("\\")) value = value.Substring(0, value.Length - 1); Directory = value; } } </script>

10. 现在连输出目录也有了,该想办法写些函数来完成将数据库架构传递给模板的工作啦,在test.cst文件的末尾 输入如下代码:

代码

<script runat="template"> //生成实体Entity类 private void GenerateEntityClasses() { CodeTemplate Template = new EntityTemplate(); foreach(TableSchema table in this.SourceDatabase.Tables) { string FileDirectory = OutputDirectory + "\\" + table.Name + ".cs"; //生成模板 Template.SetProperty("Table",table); //文件输出 Template.RenderToFile(FileDirectory,true); Debug.WriteLine(FileDirectory +" 创建成功."); } } </script>

CodeTemplateTemplate = new EntityTemplate(); 就是创建了一个新的模板

foreach(TableSchematable in this. SourceDatabase.Tables){} 表示循环输出数据库中的表

Template.SetProperty(“Table”,table); 就是向模板设置属性,还记得我们在Entity.cst里面设置了一个Table属性吗,我们就是通过这个方法给这个属性设值的.

Template.RenderToFile(FileDirectory,true); 表示将Temlate里的内容全部输出到FileDirectory目录中,true表示如果文件存在直接覆盖.

11. 函数写好了,离成功不远啦,我们在test.cst的最后再添加如下代码,用于调用刚刚写好的函数.至此,模板 文件的制作已经完成.

<% //创建实体层Entity类 this.GenerateEntityClasses(); Debug.WriteLine("OK"); %>

12. 好啦,现在只要设置我们要导出的数据库和输出目录就可以运行看结果啦,点击CodeSmith主窗体右下角Properities面板中 SourceDatabase属性栏右侧的…按钮,弹出数据库设置对话框,我们要在此添加一个新的数据库连接:

13. 点击Add按钮,属性设置如图,我们选择的是在前一章用PowerDesigner创建好的PD_test数据 库:

14. 点击OK,回到数据库选择对话框,选择刚刚创建好的数据库连接:

15. 接着是设置目标文件输出目录,我在这里设置为桌面的一个新建文件夹:

16. OK,万事俱备,可以点击运行按钮让CodeSmith为我们批量生成代码啦:

打开生成的文件,就可以看到我们期待看到的代码啦:

好了,这些是基础,但是只要你掌握了这些就可以开始自己的CodeSmith之旅啦,我也只能送大家到此咯~其他更多的 知识点希望大家能自行查看帮助文章或者上网查询,很高兴又和大家分享了自己的一点心得,接下来想再回头复习一下设计模式,也打算写一些文章,欢迎大家关 注~

上述实践中的文件源代码:

test.cst

<%-- 作者:黄聪 网址:http://www.cnblogs.com/huangcong --%> <%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="NetTiers main template." Debug="True" ResponseEncoding="UTF-8"%> <%-- 注册实体层Entity模板 --%> <%@ Register Name="EntityTemplate" Template="WinformTier\Entity.cst" MergeProperties="Flase" ExcludeProperties=""%> <%-- 数据库 --%> <%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" DeepLoad="True" Optional="False" Category="01. Getting Started - Required" Description="Database that the tables views, and stored procedures should be based on. IMPORTANT!!! If SourceTables and SourceViews are left blank, the Entire Database will then be generated." %> <% //创建实体层Entity类 this.GenerateEntityClasses(); Debug.WriteLine("OK"); %> <script runat="template"> //生成实体Entity类 private void GenerateEntityClasses() { CodeTemplate Template = new EntityTemplate(); foreach(TableSchema table in this.SourceDatabase.Tables) { string FileDirectory = OutputDirectory + "\\" + table.Name + ".cs"; //生成模板 Template.SetProperty("Table",table); //文件输出 Template.RenderToFile(FileDirectory,true); Debug.WriteLine(FileDirectory +" 创建成功."); } } </script> <script runat="template"> //解决方案输出路径 private string Directory = String.Empty; [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))] [Optional, NotChecked] [DefaultValue("")] public string OutputDirectory { get { return Directory; } set { if (value.EndsWith("\\")) value = value.Substring(0, value.Length - 1); Directory = value; } } </script>
Entity.cst

<%-- 作者:黄聪 网址:http://www.cnblogs.com/huangcong --%> <%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="NetTiers main template." Debug="True" ResponseEncoding="UTF-8"%> <%@ Assembly Name="SchemaExplorer" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Property Name="Table" Type="TableSchema" DeepLoad="True" Optional="False" Category="01. Getting Started - Required" Description="Database that the tables views, and stored procedures should be based on. IMPORTANT!!! If SourceTables and SourceViews are left blank, the Entire Database will then be generated." %> using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Entity { public partial class <%= Table.Name%> { <% foreach(ColumnSchema col in Table.Columns){ %> public <%= col.DataType %> <%= col.Name %>{ get;set; } <% } %> } }

出处:http://www.cnblogs.com/huangcong/archive/2010/06/14/1758201.html

本文版权归作 者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]IIS处理模型及ASP.NET页面生命周期

mikel阅读(1204)

[转载]IIS处理模型及ASP.NET页面生命周期 – GodSpeed – 博客园.

本文是基于IIS6的处理模型。

当一个客户端页面访问IIS试图获取一 些信息的时候,发生了什么事情?一个请求在通过了HTTP管道后又发生了什么?本文主要是描述这两个过程,即IIS处理ASP.NET请求和 ASP.NET的页面生命周期。欢迎大家积极拍砖,共同学习,共同进步。

首先我们要弄清楚两个非常重要的概念:

1, worker process(w3wp.exe). worker process管理所有的来自客户端的请求并给出响应。它是IIS下asp.net应用程序的核心。

2, application pool. 它是worker process的容器,IIS5及之前的IIS版本均没有application pool的概念。每一个application  pool对应着一个worker process,IIS Metabase中维护着Application Poolworker processMapping。这就避免了IIS5中出现的worker process(IIS5中是aspnet_wp.exe,同一时间只能运行一个该进程)崩溃,application全崩溃的局面。

客户端 向IIS发出一个资源请求后发生了如下事情:

1, server接受该请求

IIS6 通过内核模式(Kernel mode)中的HTTP.SYS来分发各个 Request到application pool。 这并不是随机的过程,在application pool创建的时候就已经注册到了HTTP.SYS,所以当请求来到时HTTP.SYS会直接发送到相应的application pool。 接下来在IIS的用户模式(User mode)中,Web Admin Services (WAS) 做了从HTTP.SYS中得到Request并分发到application pool的工作。application pool直接把request传递给worker process。

2, 请求传递到worker process后,worker process初始化加载ASP.NET ISAPI(Internet Server Application

Program Interface)ASP.NET ISAPI进而加载CLR创建托管环境。

(注:ISAPI只是一个接口,起到一个代理的作用,主要 能力就是根据Request URL的后缀来寻找该后缀的处理程序)

ASP.NET ISAPI定义在aspnet_isapi.dll中,它本身运行在一个非托管的环境中。ASP.NET ISAPI开始一个HttpRuntime, HttpRuntime调用ProcessRequest方法来开始处理请求。ProcessRequest根据ISAPI传进来的iWRType来创建不同的HttpWorkerRequest,从而屏蔽了不同IIS的差异。 接下来ProcessRequest方法创建了HttpContext,我们使用HTTPContext.Current来访问它。在 HttpRuntime使用HttpApplicationFactory创建了HttpApplication对象(IHttpHandler)以后, 所有的请求都会在通过httpmodule后找到相应的Httphandler进行处理。在HttpApplicationFactory创建 HttpApplication之前,会查找config(web.config和Machine.config)文件中注册的所有的HttpModule,并 根据配置信息加载相应的Assembly,通过Reflection创建对应的HttpModule,并将这些Module加到HttpApplication _moduleCollection Filed中。我们对一个Application的请求最终会落到一个HttpApplication对象 上。当一个请求到来时,ASP.NET会在Httplication Pool中查找未被使用的HttpApplication对象。

3, 请求通过HTTP管道后,每个请求都发向相关的各自的httphandler,IIS请求处理过程结束。

HttpHandler 是HTTP管道的终点,它为每个request生成输出。System.Web.UI.Page就是这样一个典型的Httphandler,当我们请求一个aspx页面,这个HttpHandler生成html发送回客户端。看Page类的签名:

public class Page : TemplateControl, IHttpHandler

{
}

可以看 到,Page类就是一个HttpHandler。

综上整个过程就是:当客户端向服务器发送资源请求时,请求首先到达IIS的HTTP.SYS。 然后HTTP.SYS发送请求道对应的Application Pool。 然后Application Pool发送请求到Worker Process(W3WP.exe) 中加载ISAPI Extension,ISAPI创建一个HttpRuntime对象来通过HttpModule和HttpHandler处理请求。 然后页面生命周期就开始了。

4, 页面生命周期开始

页面生命周期的主要阶段包括:

页 面初始化(Init): 服务器创建服务器控件的实例

加 载(load): 控件实例被加载到它定义的页面对象中

预 输出:(PreRender) 对控件的更改被更新,准备输出。

保 存(SaveViewState): 控件的状态信息被保存。输出页面(Render):服 务器为控件创建html标记。

处 理(Dispose): 主要做的工作就是dispose, 关闭数据库连接,文件资源的释放等。

卸 载(Unload):销毁服务器控件的实例

页面生命周期的主要事件:

PreInit:

  1. 检查IsPostBack 属性
  2. 动 态设置Master Page
  3. 动态设置Theme
  4. 设置控件的默认值(UniqueId等)
  5. 重新创 建动态控件(初始化控件),初始化控件的值

Init: 这个时间发生在所有的控件被初始化,所有的皮肤设置被应用以后。它用来读取或者初始化控件属性。它能够用来注册一些aspx页面中没有指出的控件的事件。
InitComplete: Use this event for processing tasks that require all initialization to be complete.

PreLoad: 加载页面的ViewState和所有的控件,然后处理所有的包含在Request实例中的postback数据。

Load: 这个事件可能是大家最熟悉的了。需要注意的是,Page对象会递归的调用子控件的onload事件直到页面和所有的子控件被加载完成。这个事件主要用来设 置控件属性的值,建立数据库连接(通常不这么做)。

Control events: 这个就不多说了,主要是处理控件的事件,例如click。这也就让我们明白了每次我们click一个Button的时候,实际上是要先去执行load事件 然后才执行click事件的,一般我们用!IsPostBack来判断一下从而避免执行不必要的加载逻辑。

LoadComplete: 页面所有的控件都被加载以后执行,暂时没有想到用来干什么。。。

PreRender: 在HTML被生成之前这是最后一个事件。每一个页面中的控件都有PreRender的过程。在这里对将要输出的HTML结果进行最后一次修改。

SaveStateComplete: 在这个时间发生之前,已经保存了所有控件和页面的,任何对page或者控件的改动都不会产生左右。暂时没想到用来干啥。

Render: 它不是一个事件而是一个方法。工作就是把HTML写回客户端浏览器。

UnLoad: 页面中的每一个控件都会发生这件事。在控件中,使用这个事件来做清理工作,例如关闭数据库连接等。对与页面本身也是做清理工作,例如关闭打开的文件和数据 库连接,或者结束日志或者其它指定的工作。

需要说明的是,每次Request都会创建一个全新的Page类的实例, 所以在页面中的自己定义的字段是不能在两次request中传递值的,需要使用viewstate来存储。

5, HttpHandler根据页面生命周期中事件的处理把结果发回IIS,IIS再把结果发回客户端浏览器。

值得注意的是,在这个过程中请求会再次通过HttpModule(注册一个EndRequest事件)。

至此,整个Request结束。欢迎补充及对不准确的地方进行指正,拍砖。谢谢。

[转载]ActiveReport在.net中的简单应用,子报表制作

mikel阅读(1156)

[转载]ActiveReport在.net中的简单应用,子报表制作 – 挂在墙上的天堂 – 博客园.

先上图,最终效果如下:

image

可以连续打印。

具体功能就是大报表里面再套一个子报表。

考察了几个报表控件,在b/s下面ActiveReport还是比较好用的,简单,实用

具体步骤如下:

1、安装ActiveReports for .NET 3.0 Setup.exe,到官网自己下。

2、用自己的金钱、魅力、或者智慧注册之~~~~~不注册也可以用,不过报表上会有红色字体提示。

3、在项目中新建报表文件

image

4、在新建的报表文件上右键选择“视图设计器”,直接双击的话就会用vs代码编辑器打开,这里b/s和c/s是不一样的。c/s里面双击就是视图设 计器了。

image

5、和设计网页一样,在页面上布置各种控件

image

画完的页面如下:

image

在左上角的地方有个按钮,image ,这里面可以更改报表的信息,如纸张大小、纸张方向等,我选的就是A4纸、横向

image

这里不多说了,注意设定好页面里面每个地方的绑定字段,另外在右侧有一个子报表SubReport,在这里

image

这个放后面说~~~

点上面的数据库图标可以直接连接数据库进行测试,这个自己试验就ok,实际应用时都是用代码控制,这里控制太不灵活。另外需要说明的一点是,可以在 这里把测试数据提取出来,方便选择每个地方的字段~~~不多说了,看图

image

6、下面开始做现实报表的网页

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ZhunKaoZheng.aspx.cs" Inherits="ExamSys.Report.ZhunKaoZheng" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
    <meta name="GENERATOR" content="Microsoft Visual Studio 7.0">
        <meta name="CODE_LANGUAGE" content="C#">
        <meta name="vs_defaultClientScript" content="VBScript">
        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        <link rel="stylesheet" type="text/css" href="default.css">
</head>
<body>
    <form id="ActiveXExport" method="post" runat="server">
        </form>

    <div id="pagebody">

            <object id="arv" codebase="arview2.cab#version=-1,-1,-1,-1" height="800" width="100%" 
classid="clsid:8569D715-FF88-44BA-8D1D-AD3E59543DDE" viewastext>
                <param name="_ExtentX" value="26141">
                <param name="_ExtentY" value="11959">
            </object>
            <script language="vbscript">
            <!--
            sub arv_ControlLoaded()
                arv.DataPath = "ZhunKaoZheng.aspx?ReturnReport=1"
            end sub
            -->
            </script>

        </div>
</body>
</html>

需要注意的是我这个控件是引用在form外面的,在里面不好使哦!!!

还有这个

arv.DataPath = "ZhunKaoZheng.aspx?ReturnReport=1"
是必须加的,记得ZhunKaoZheng.aspx就是本页面的地址,具体为什么加我也不知道,谁知道为啥记得告诉我哦。
后台代码如下:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using DataDynamics.ActiveReports;
using ExamSys.DBUtility;
using System.Data.SqlClient;
using System.Data;

namespace ExamSys.Report
{
    public partial class ZhunKaoZheng : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string strSql="";
            if (Session["personid"].ToString() != "" && Session["personid"] != null)
            {

                strSql = @"SELECT T_PERSON.ID, T_PERSON.NAME, T_PERSON.PHOTO,
      T_PERSON.BH_SHENFENZHENG, T_PERSON.BAOMING_NO, T_PERSON.DEP,
      ExamUser.examID, T_PERSON.DEP_BIANHAO,
      T_INFO.NAME AS DEP_NAME, ExamList.elClass
FROM ExamList INNER JOIN
      ExamUser ON ExamList.elID = ExamUser.elID INNER JOIN
      T_PERSON ON ExamUser.personID = T_PERSON.ID INNER JOIN
      T_INFO ON T_PERSON.DEP_BIANHAO = T_INFO.ID
WHERE (T_PERSON.ID = '" + Session["personid"].ToString() + @"')";

            }

            else
            {

                strSql = @"SELECT T_PERSON.ID, T_PERSON.NAME, T_PERSON.PHOTO,
      T_PERSON.BH_SHENFENZHENG, T_PERSON.BAOMING_NO, T_PERSON.DEP,
      ExamUser.examID, T_PERSON.DEP_BIANHAO,
      T_INFO.NAME AS DEP_NAME, ExamList.elClass
FROM ExamList INNER JOIN
      ExamUser ON ExamList.elID = ExamUser.elID INNER JOIN
      T_PERSON ON ExamUser.personID = T_PERSON.ID INNER JOIN
      T_INFO ON T_PERSON.DEP_BIANHAO = T_INFO.ID
WHERE (T_PERSON.DEP_BIANHAO = '" + Session["dep"].ToString() + @"') AND 
(ExamUser.elID IN (SELECT ELID FROM EXAMLIST AS EXAMLIST_1 WHERE (ELCLASS = '" + Session["bigtitle"].ToString() + "')))";

            }
            strSql = strSql.Replace("\r", " ").Replace("\n", " ");
            DataSet myDS = SQLHelper.GetDataSet(strSql);
            DataTable myDT = GetDistinctTable(myDS.Tables[0], "id");

            string sReturnReport = this.Page.Request.QueryString["ReturnReport"];
            if ((sReturnReport != null) && (sReturnReport.Trim().Length != 0))
            {
                this.Page.Response.Buffer = true;
                ActiveReport3 rpt = null;
                try
                {
                    //这两句话是重点
                    rpt = new rptZhunKaoZheng();
                    rpt.DataSource = myDT;
                    rpt.DataMember = myDT.TableName;
                    rpt.Run(false);
                }
                catch (DataDynamics.ActiveReports.ReportException eRunReport)
                {
                    this.Trace.Warn("Report failed to run:\n" + eRunReport.ToString());
                }
                MemoryStream outStream = new MemoryStream();
                rpt.Document.Save(outStream, DataDynamics.ActiveReports.Document.RdfFormat.AR20);
                outStream.Seek(0, SeekOrigin.Begin);
                byte[] bytes = new byte[outStream.Length];
                outStream.Read(bytes, 0, (int)outStream.Length);
                this.Page.Response.ClearContent();
                this.Page.Response.ClearHeaders();
                this.Page.Response.BinaryWrite(bytes);
                this.Page.Response.End();
            }
        }

        /// <summary>
        /// 获取对固定列不重复的新DataTable
        /// </summary>
        /// <param name="dt">含有重复数据的DataTable</param>
        /// <param name="colName">需要验证重复的列名</param>
        /// <returns>新的DataTable,colName列不重复,表格式保持不变</returns>
        private DataTable GetDistinctTable(DataTable dt, string colName)
            {
                DataView dv = dt.DefaultView;
                DataTable dtCardNo = dv.ToTable(true, colName);
                DataTable Pointdt = new DataTable();
                Pointdt = dv.ToTable();
                Pointdt.Clear();
                for (int i = 0; i < dtCardNo.Rows.Count; i++  )
                {
                    string ss=dtCardNo.Rows[i][0].ToString();
                    DataRow dr = dt.Select(colName +"="+ ss)[0];
                    Pointdt.Rows.Add(dr.ItemArray);
                }
                return Pointdt;
            }

    }
}

为了确保能看的清楚,无关的代码我也不删除了。里面最重要的是

rpt = new rptZhunKaoZheng();
rpt.DataSource = myDT;
rpt.DataMember = myDT.TableName;
rpt.Run(false);
7、这样主报表就现实成功了,下面开始子报表的制作~~

8、同样的方法建立子报表模板

image

注意里面的标题栏为groupHeader,子报表的标题一定要选这个,不然不能在主报表里面现实,可以右键选择添加、删除标题栏

image

在里面设定好需要显示的字段就O了

9、更改主报表

1)选择主报表的detail模块,添加Format事件,这里面主要设置子报表的DataSource和DataMember

image

        private void detail_Format(object sender, EventArgs e)
        {
            //string strSql1 = "SELECT EXAMLIST.ELNAME, SiteInfo.siName, T_PSSBSchema.seatnum, ExamOrder.eoBegin, 
ExamOrder.eoEnd FROM T_PSSBSchema INNER JOIN SiteInfo ON 
T_PSSBSchema.siID = SiteInfo.siID INNER JOIN ExamOrder ON 
SiteInfo.siID = ExamOrder.siID INNER JOIN EXAMLIST ON T_PSSBSchema.elID = EXAMLIST.ELID 
AND ExamOrder.elID = EXAMLIST.ELID WHERE (T_PSSBSchema.examID = '" + this.label9.Text + "')";
            string strSql = @"SELECT ExamList.elName, SiteInfo.siName, ExamUser.seatnum, ExamOrder.eoBegin,
      ExamOrder.eoEnd
FROM ExamUser INNER JOIN
      SiteInfo ON ExamUser.siID = SiteInfo.siID INNER JOIN
      ExamOrder ON SiteInfo.siID = ExamOrder.siID INNER JOIN
      ExamList ON ExamUser.elID = ExamList.elID AND
      ExamOrder.elID = ExamList.elID
WHERE (ExamUser.examID = '" + this.label9.Text + "')";
            strSql = strSql.Replace("\r", " ").Replace("\n", " ");
            DataTable myDT = SQLHelper.GetDataSet(strSql).Tables[0];
            Time2CharConvert(myDT, "eoBegin", "f");
            Time2CharConvert(myDT, "eoEnd", "t");
            this.srptKaoChang.Report.DataSource = myDT;
            this.srptKaoChang.Report.DataMember = myDT.TableName;
            //((DataDynamics.ActiveReports.DataSources.SqlDBDataSource)this.srptKaoChang.Report.DataSource).ConnectionString = 
"data source=127.0.0.1;initial 
catalog=kuaiji;password=sa;persist security info=True;user id=sa";
            //((DataDynamics.ActiveReports.DataSources.SqlDBDataSource)
this.srptKaoChang.Report.DataSource).SQL = 
"SELECT EXAMLIST.ELNAME, SiteInfo.siName, T_PSSBSchema.seatnum, ExamOrder.eoBegin, ExamOrder.eoEnd FROM T_PSSBSchema 
INNER JOIN SiteInfo ON T_PSSBSchema.siID = SiteInfo.siID 
INNER JOIN ExamOrder ON SiteInfo.siID = ExamOrder.siID INNER JOIN EXAMLIST 
ON T_PSSBSchema.elID = EXAMLIST.ELID AND ExamOrder.elID = EXAMLIST.ELID 
WHERE (T_PSSBSchema.examID = '" + this.label9.Text + "')";

        }

10、选择报表主体,添加ReportStart和ReportEnd事件。

image

rptKaoChang _rptKaoChang = null;
        private void rptZhunKaoZheng_ReportStart(object sender, EventArgs e)
        {
            //Check to see if the holder subreport object is assigned, if not create it
            //Creating the subreport here will only create one instance to use
            if (_rptKaoChang == null)
            {
                _rptKaoChang = new rptKaoChang();
                this.srptKaoChang.Report = _rptKaoChang;
                this.srptKaoChang.Report.DataSource = new DataDynamics.ActiveReports.DataSources.SqlDBDataSource();
            }
        }

        private void rptZhunKaoZheng_ReportEnd(object sender, EventArgs e)
        {
            //clean up existing subreport document object
            _rptKaoChang.Document.Dispose();
            //clean up existing subreport object
            _rptKaoChang.Dispose();
            //Reset subreport to null, so if this report is called again it will reinit inside the section format event
            _rptKaoChang = null;
        }

在此进行子报表的初始化和关闭。

11、结束战斗,测试OK~~~

[转载]学习ASP.NET MVC之怎样设计友好的URL

mikel阅读(898)

[转载]学习ASP.NET MVC之怎样设计友好的URL – .NET之旅 – 博客园.

设计页面的URL和设计页面中的文字、图片同样重要,最终网站用户很容易 会注意到浏览器的地址栏,一个好的URL容易被用户记住和理解。

下面列出怎样设计一个友好的URL

1、尽量使URL简洁、清晰易懂

首先我们要 明确,我们设计一个URL样式要从最终用户的角度出发,而不是开发者,可以忽略技术架构。设计URL应描述网站的主题内容,而不是网站内容的细节。如使用/Articles/AnnualReport而不是/Website_v2/CachedContentSercer/FormCache/AnnualReportURL在能表达网站内容的基础上应尽可能的简洁、清晰易懂,而不需要描述具体的细节。ASP.NET MVC中的实现方法为,在Global.asax中添加route,代码如下:

routes.MapRoute(
null,
{controller}/{action}/{id},
new { controller = Articles, action = AnnualReport }
);

2、避免暴露数据库ID

优先使用内容标题而不是ID号。如使用/Articles/AnnualReport/what-is-aspnet-mvc而不是/Articles/AnnualReport /6034。如果我们设计URL时需要一个唯一标识来区分不同的内容,这时通常会使用数据库的主键,而主键通常是自动编号的整数。不巧的 是,如上面的URL中的数字6034对于最终用户来说没用什么意义。对于这种情况,可以将内容标题和ID号结合起来。如页面内容为什么事ASP.NET MVC,URL设计为/Articles/AnnualReport/6034/what-is-aspnet-mvc。虽然输入时起来比较 麻烦,但是对于用户可读性来说更有意义以及提高搜索引擎收录。ASP.NET MVC中的实现方法为,在Global.asax中添加route,代码如下:

routes.MapRoute(
null,
{controller}/{action}/{id}/{describe},
new { controller = Articles, action = AnnualReport },
new { id = @”\d+ } //限定id为数字
);

3、设计可编辑、有意义的URL

当设计一个URL样式时,有必要考虑怎样使URL可编辑,即用户可以根据当前的URL来推测相关页面的URL样式。例如:下表为网站事件管理程序的URL样式

URL

描述

http://example.com/events

显示所有的事件

http://example.com/events/<year>

显示某年的所有事件

http://example.com/events/<year>/<month>

显示某年某月的所有事件

http://example.com/events/<year>/<month>/<date>

显示某年某月某日的所有事件

这样的URL设计会使你的网站更为灵活,虽然实际页面中会包含这种级 别分类显示的导航页面,但是对于那些喜欢自己编辑URL的用户来说则更为有意义。如用户当前是看20106月发生的所有事件,当用户想回顾5月发生的所有事件时,他只要将URL中的6改为5即可。

4URL避免使用空格

如果你觉得URL的文本太长,横杠 是 个不错的选择 (如,my-great-article)。而不要使用下划线,点或其它的字符做分割。URL编码器会把一些字符编码为其他字符串,如将空格编码为%20

5URL应该是持久有效链接

不要改变URL链接,破坏链接会失去一些用户。当你的URL被用户记住、保存、收藏了,如果你的URL改变了,这部分用户可能会失去。即使要改变URL,也需要继续的支持原来老的URL重定向到新的URL

综上所述,URL的设计应该是简洁易懂的,易于输入的,用户可编辑的,持 久有效的,能体现网站的导航结构的等。欢迎大家继续扩展!

参考文献:

Steven Sanderson Pro ASP.NET MVC Framework》;

Jeffrey Palermo,Ben Scheirman,Jimmy Bogard ASP.NET MVC in Action》。

版权声明

作者:wanjiabao

出处:http://www.cnblogs.com/wanjiabao/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]Asp.net MVC 2 使用Areas功能的常见错误

mikel阅读(991)

[转载]Asp.net MVC 2 使用Areas功能的常见错误 – Taven – 博客园.

开发工具:VS2010中文旗舰版

出错的信息:

错误信息

找到了多个与名为“Home”的控制器匹配的类型。如果为此请求 (“{controller}/{action}/{id}”)提供服务的路由没有指定命名空间 来搜索匹配此请求的控制器,则会发生此情况。如果是这样,请通过调用采用“namespaces”参数的“MapRoute”方法的重载来注册此路由。

对 “Home”的请求找到了下列匹配的控制器:
MvcApplication1.Areas.Web.Controllers.HomeController
MvcApplication1.Areas.Admin.Controllers.HomeController

问题出现步骤:

1、新建ASP.NET MVC 2 空项目

2、添加两个Area,分别为Admin和WebSite(一个为后台,另一个为前台)

3、在两个Area中分别添加Home控制器,并分别为各Home控制器的Index方法创建视图文件

4、完成后,如下图:

注意,不使用Area的MVC程序中是不区分Cotroller的命名空间的,但是使用了Area的MVC程序是区分Cotroller的命名空间 的.其合法的规则是“控制器的命名空间必须在Area的命名空间之下”,假设:

AdminAreaRegistration.cs中的命名空间为:MvcApplication1.Areas.Admin,那么控制器的命名空 间必须为:MvcApplication1.Areas.Admin.xxx.xxxx ,也就是命名空间的前导部分必须是一致,否则会提示错误。

另外除了这里以外,在Global.asax.cs文件的代码中,将

代码

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(
{resource}.axd/{*pathInfo});

routes.MapRoute(
Default, // 路由名称
{controller}/{action}/{id}, // 带有参数的 URL
new { controller = Home, action = Index, id = UrlParameter.Optional } // 参数默认值

);

}

中的 controller = “Home” 修改为一个没有重名的控制器名称,否则也会报同样的错误的,这里我们可以改为 controller = “Default”。

还有没有更简单,更灵活的方法? 当然有,最直接的方法是修改AdminAreaRegistration.cs 和 WebAreaRegistration.cs 中的路由设置,将其控制器的命名空间传入给系统,以修改 WebAreaRegistration.cs 为例子:

代码

public override void RegisterArea(AreaRegistrationContext context)
{
//context.MapRoute(
// “Web_default”,
// “Web/{controller}/{action}/{id}”,
// new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
//);

//直接将命名空间传入
context.MapRoute(
Web_default,
Web/{controller}/{action}/{id},
new { controller = Home, action = Index, id = UrlParameter.Optional },
new string[] { MvcApplication1.Areas.Web.Controllers }
);

}

OK,结束了,希望大家多多交流!

可成功运行的源码Demo下载:/Files/taven/MvcApplication1.rar

作者:Taven.李锡远
出处:http://taven.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]Lucene 原理与代码分析完整版PDF下载

mikel阅读(1059)

[转载]Lucene 原理与代码分析完整版 – 觉先 – 博客园.

Lucene 原理与代码分析系列文章已经基本告一段落,可能问题篇还会有新的更新。

完整版pdf可由以下链接下载。

Lucene 原理与代码分析完整版

目录如下:

目录

目 录

第 一篇:原理篇

第 一章:全文检索的基本原理

一、 总论

二、 索引里面究竟存些什么

三、 如何创建索引

第 一步:一些要索引的原文档(Document)

第 二步:将原文档传给分次组件(Tokenizer)

第 三步:将得到的词元(Token)传给语言 处理组件(Linguistic Processor)

第 四步:将得到的词(Term)传给索引组件(Indexer)

1. 利用得到的词(Term)创建一个字典。

2. 对字典按字母顺序进行排序。

3. 合并相同的词(Term)成为文档倒排(Posting List)链表。

四、 如何对索引进行搜索?

第一步:用户输入查询语句。

第二步:对查询语句进行词法分析,语法分析,及语言处理。

1. 词法分析主要用来识别单词和关键字。

2. 语法分析主要是根据查询语句的语法规则来形成一棵语法树。

3. 语言处理同索引过程中的语言处理几乎相同。

第三步:搜索索引,得到符合语法树的文档。

第四步:根据得到的文档和查询语句的相关性,对结果进行排序。

1. 计算权重(Term weight)的过程。

2. 判断Term之 间的关系从而得到文档相关性的过程,也即向量空间模型的算法(VSM)

第 二章:Lucene的总体架构

第二篇:代码分析篇

第三章:Lucene的索引文件格式

一、 基本概念

二、 基本类型

三、 基本规则

1. 前缀后缀规则(Prefix+Suffix)

2. 差值规则(Delta)

3. 或然跟随规则(A, B?)

4. 跳跃表规则(Skip list)

四、具体格式

4.1. 正向信息

4.1.1. 段的元数据信息(segments_N)

4.1.2. (Field)的元数据信息(.fnm)

4.1.3. (Field)的数据信息(.fdt.fdx)

4.1.3. 词向量(Term Vector)的数据信息(.tvx.tvd.tvf)

4.2. 反向信息

4.2.1. 词典(tis)及 词典索引(tii)信息

4.2.2. 文档号及词频(frq)信息

4.2.3. 词位置(prx)信息

4.3. 其他信息

4.3.1. 标准化因子文件(nrm)

4.3.2. 删除文档文件(del)

五、总体结构

第 四章:Lucene索引过程分析

一、索引过程体系结构

二、详细索引过程

1、创建IndexWriter对象

2、创建文档Document对象,并加入域(Field)

3、将文档加入IndexWriter

4、将文档加入DocumentsWriter

4.1、得到当前线程对应的文档集处理对象(DocumentsWriterThreadState)

4.2、用得到的文档集处理对象(DocumentsWriterThreadState)处理文档

4.3、用DocumentsWriter.finishDocument结束本次文档添加

5DocumentsWriterCharBlockPoolByteBlockPoolIntBlockPool的缓存管理

6、关闭IndexWriter对象

6.1、得到要写入的段名

6.2、将缓存的内容写入段

6.3、生成新的段信息对象

6.4、准备删除文档

6.5、生成cfs

6.6、删除文档

第 五章:Lucene段合并(merge)过程分析

一、段合并过程总论

1.1、合并策略对段的选择

1.2、反向信息的合并

二、 段合并的详细过程

2.1、将缓存写入新的段

2.2、选择合并段,生成合并任务

2.2.1、用合并策略选择合并段

2.2.2、注册段合并任务

2.3、段合并器进行段合并

2.3.1、合并存储域

2.3.2、合并标准化因子

2.3.3、合并词向量

2.3.4、合并词典和倒排表

第 六章:Lucene打分公式的数学推导

第七章:Lucene搜索过程解析

一、Lucene搜索过程总论

二、Lucene搜索详细过程

2.1、打开IndexReader指向索引文件夹

2.1.1、找到最新的segment_N文件

2.1.2、通过segment_N文件中保存的各个段的信息打开各个段

2.1.3、得到的IndexReader对象如下

2.2、打开IndexSearcher

2.3QueryParser解析查询语句生成查询对象

2.4、搜索查询对象

2.4.1、创建Weight对象树,计算Term Weight

2.4.2、创建ScorerSumScorer对象树

2.4.3、进行倒排表合并

2.4.4、收集文档结果集合及计算打分

2.4.5Lucene如 何在搜索阶段读取索引信息

第 八章:Lucene的查询语法,JavaCCQueryParser

一、Lucene的查询语法

二、JavaCC介绍

2.1、第一个实例——正整数相加

2.2、扩展语法分析器

2.3、第二个实例:计算器

三、解析QueryParser.jj

3.1、声明QueryParser

3.2、声明词法分析器

3.3、声明语法分析器

第 九章:Lucene的查询对象

1BoostingQuery

2CustomScoreQuery

3MoreLikeThisQuery

4MultiTermQuery

4.1TermRangeQuery

4.2NumericRangeQuery

5SpanQuery

5.1SpanFirstQuery

5.2SpanNearQuery

5.3SpanNotQuery

5.4SpanOrQuery

5.5FieldMaskingSpanQuery

5.6PayloadTermQueryPayloadNearQuery

6FilteredQuery

6.1TermsFilter

6.2BooleanFilter

6.3DuplicateFilter

6.4FieldCacheRangeFilter<T>FieldCacheTermsFilter

6.5MultiTermQueryWrapperFilter<Q>

6.6QueryWrapperFilter

6.7SpanFilter

6.7.1SpanQueryFilter

6.7.2CachingSpanFilter

第十章:Lucene的分词器Analyzer

1、抽象类Analyzer

2TokenStream抽象类

3、几个具体的TokenStream

3.1NumericTokenStream

3.2SingleTokenTokenStream

4Tokenizer也是一种TokenStream

4.1CharTokenizer

4.2ChineseTokenizer

4.3KeywordTokenizer

4.4CJKTokenizer

4.5SentenceTokenizer

5TokenFilter也是一种TokenStream

5.1ChineseFilter

5.2LengthFilter

5.3LowerCaseFilter

5.4NumericPayloadTokenFilter

5.5PorterStemFilter

5.6ReverseStringFilter

5.7SnowballFilter

5.8TeeSinkTokenFilter

6、不同的Analyzer就是组合不同的TokenizerTokenFilter得到最后的TokenStream

6.1ChineseAnalyzer

6.2CJKAnalyzer

6.3PorterStemAnalyzer

6.4SmartChineseAnalyzer

6.5SnowballAnalyzer

7Lucene的 标准分词器

7.1StandardTokenizerImpl.jflex

7.2StandardTokenizer

7.3StandardFilter

7.4StandardAnalyzer

8、不同的域使用不同的分词器

8.1PerFieldAnalyzerWrapper

第三篇:问题篇

问 题一:为什么能搜的到“中华 AND 共和 国”却搜不到“中华共和国”?

问 题二:stemminglemmatization的关系

问题三:影响Lucene对文档打分的四种方式

在索引阶段设置Document BoostField Boost,存储在(.nrm)文件中。

在 搜索语句中,设置Query Boost.

继 承并实现自己的Similarity

继 承并实现自己的collector

问 题四:Lucene中的TooManyClause异常

问题五:Lucene的事务性

问 题六:用Lucene构建实时的索引

1、初始化阶段

2、合并索引阶段

3、重新打开硬盘索引的IndexReader

4、替代IndexReader

5、多个索引

[转载]XML和XSLT结合使网站设计浑然一体

mikel阅读(990)

[转载]XML和XSLT结合使网站设计浑然一体.

XML和XSLT的转换使Web设计受益无穷。借助XML和 XSLT转换,你可以实现将动态用语(dynamic verbiage)和网站内容存储在数据库中。你可以在XML中传输数据库,然后再通过XSLT转换将其转变为HTML脚本。

在网络发展初期,凝聚性(cohesiveness)是由服务器端实现的,但要牵涉到大量的人工文件管理工作。幸运的是,随着网络的日益成熟, 网络开发工具也日臻完善。例如,在.NET框架下,你可以创建各种Web控件来统一设计。

在设计用户/数据交互功能时,如何让数据的完整性、用户界面的功能性和商务规则的完善实现。本文将提供一个网站实例,并说明XML 和XSLT如何使你的网站设计浑然一体。
以下是引用片段:

<html>
<head>
</head>
<body>
<form method=”POST” name=”thisForm” id=”thisForm” action=”somepage.php”>
<input type=”text” name=”txtText” id=”txtText” size=”25″><br>
<input type=”submit” name=”btnSubmit” id=”btnSubmit” value=”Submit”>
</form>
</body>
</html>

以上代码段完成了主要功能,但还需用XML和XSLT来对其加以美化。

在XML中,代码有开头和结尾标签,而在HTML中没有。INPUT 和BR标签是个特例,它们不需结尾标签。然而,在结尾标签标记“>”前加一个正斜杠,可确保HTML符合XML规范。如果在编写HTML脚本时注意 遵从这些规范,你就能够将XML/HTML(aka XHTML)转换为不错的HTML页面。

以下是引用片段:

<form method=”POST” name=”thisForm” id=”thisForm” action=”somepage.php”>
<input type=”text” name=”txtText” id=”txtText” size=”25″ transform=”blueText”/>
<br/>
<input type=”submit” name=”btnSubmit” id=”btnSubmit” value=”Submit”
transform=”bigButton”/>
</form>

运行下列代码,完成XSLT转换:

<?xml version=”1.0″?>
<xsl:stylesheet
xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” version=”1.0″
>
<xsl:output method=”html”/>
<xsl:template match=”/”>
<table width=”100%” cellpadding=”0″ cellspacing=”0″>
<tr><td align=”center”>This is the defined header</td></tr>
<tr><td><xsl:apply-templates select=”//form”/></td></tr>
<tr><td align=”center”>This is the defined footer</td></tr>
</table>
</xsl:template>
<xsl:template match=”form”>
<xsl:element name=”form”>
<xsl:attribute name=”method”><xsl:value-of
select=”@method”/></xsl:attribute>
<xsl:attribute name=”action”><xsl:value-of
select=”@action”/></xsl:attribute>
<xsl:attribute name=”name”><xsl:value-of select=”@name”/></xsl:attribute>
<xsl:attribute name=”id”><xsl:value-of select=”@id”/></xsl:attribute>
<xsl:apply-templates select=”*”/>
</xsl:element>
</xsl:template><xsl:template match=”*”>
<xsl:choose>
<xsl:when test=”@transform=’blueText'”><xsl:element name=”input”>
<xsl:attribute name=”name”><xsl:value-of select=”@name”/></xsl:attribute>
<xsl:attribute name=”id”><xsl:value-of select=”@id”/></xsl:attribute>
<xsl:attribute name=”type”>text</xsl:attribute>
<xsl:attribute name=”style”>color:blue</xsl:attribute>
<xsl:if test=”@value”><xsl:attribute name=”value”><xsl:value-of
select=”@value”/></xsl:attribute></xsl:if>
</xsl:element>
</xsl:when>
<xsl:when test=”@transform=’redText'”><xsl:element name=”input”>
<xsl:attribute name=”name”><xsl:value-of
select=”@name”/></xsl:attribute>
<xsl:attribute name=”id”><xsl:value-of
select=”@id”/></xsl:attribute>
<xsl:attribute name=”type”>text</xsl:attribute>
<xsl:attribute name=”style”>color:red</xsl:attribute>
<xsl:if test=”@value”><xsl:attribute name=”value”><xsl:value-of
select=”@value”/></xsl:attribute></xsl:if>
</xsl:element>
</xsl:when>
<xsl:when test=”@transform=’bigButton'”><xsl:element name=”input”>
<xsl:attribute name=”name”><xsl:value-of
select=”@name”/></xsl:attribute>
<xsl:attribute name=”id”><xsl:value-of
select=”@id”/></xsl:attribute>
<xsl:attribute name=”style”>height:30px;width:100px;font-
size:18pt;font-weight:700;</xsl:attribute>
<xsl:attribute name=”value”><xsl:value-of
select=”@value”/></xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

以上代码无法为你实现创建命名空间、定义XML标签、确认DTD或schema。它使你能够创建可行的HTML脚本,并可转 化为完整的新页面,无需担心设计因素。

在样式表中,用HTML标签的转换属性驱动转换操作。我曾考虑用一个FORM窗体作为定义转换操作所需的用户控件的单元,因为所有用于用户输入 的控件都应在一个FORM中。本例中,输出为一个文本INPUT,文本颜色为蓝色;一个高20像素、宽100像素的按钮,字体为18点加粗。我们可以通过 修改转换属性来改变文本框中的文本颜色。

有多种方法可将静态内容添加到网页中本例中只采用最简单的方式,即在样式表中增加header和footer。

现在,要创建一个新窗体用于用户输入时,要做的只是创建一个一般窗体。一旦一般窗体通过测试,就可以将这些窗体添加到转换中生成主题的HTML 输出。你只要记住输入控件类型,并注意把它添加为转换属性即可。

[转载]Xml中SelectSingleNode方法中的xpath用法

mikel阅读(1070)

[转载]Xml中SelectSingleNode方法中的xpath用法 – wf520pb的专栏 – CSDN博客.

  1. 最常见的XML数据类型 有:Element, Attribute,Comment, Text.
  2. Element, 指形如<Name>Tom<Name>的节点。它可以包 括:Element, Text, Comment, ProcessingInstruction, CDATA, and EntityReference.
  3. Attribute, 指在<Employee >中的粗体部分。
  4. Comment,指形如:<!– my comment –> 的 节点。
  5. Text, 指在<Name>Tom<Name>的粗体部分。
  6. 在XML中,可以用XmlNode对象 来参照各种XML数据类型。
  7. 2.1 查询已知绝对路径的节点(集)
  8. objNodeList = objDoc.SelectNodes(“Company/Department/Employees/Employee”)
  9. 或者
  10. objNodeobjNodeList = objNode.SelectNodes(“/Company/Department/Employees/Employee”)
  11. 以上两种方法可返回一个 NodeList对象,如果要返回单个节点可使用SelectSingleNode方法,该方法如果查询到一个或多个节点,返回第一个节点;如果没有查询 的任何节点返回 Nothing。例如:
  12. objNodeobjNode = objNode.SelectSingleNode(“/Company/Department/Employees/Employee”)
  13. If Not (objNode is Nothing) then
  14. ‘- Do process
  15. End If
  16. 2.2 查询已知相对路径的节点 (集)
  17. 可 使用类似于文件路径的相对路径的方式来查询XML的数据
  18. objNode = objDoc.SelectSingleNode(“Company/Department”)
  19. objNodeobjNodeList = objNode.SelectNodes(“../Department)
  20. objNodeobjNode = objNode.SelectNode(“Employees/Employee”)
  21. 2.3 查询已知元素名的节点 (集)
  22. 在 使用不规则的层次文档时,由于不知道中间层次的元素名,可使用//符号来越过中间的节点,查询其子,孙或多层次下的其他所有元素。例如:
  23. objNodeList = objDoc.SelectNodes(“Company//Employee”)
  24. 2.4 查询属性 (attribute)节点
  25. 以上的各种方法都返回元素(element)节点(集),返回属性(attribute),只需要采用相应的方 法,在属性名前加一个@符号即可,例如:
  26. objNodeList = objDoc.SelectNodes(“Company/Department/Employees/Employee/@id”)
  27. objNodeList = objDoc.SelectNodes(“Company//@id”)
  28. 2.5 查询Text节点
  29. 使用text()来获取Text节 点。
  30. objNode = objDoc.SelectSingleNode(“Company/Department/Deparmt_Name/text()”)
  31. 2.6 查询特定条件的节点
  32. 使用[]符号来查询特定条件的节点。例 如:
  33. a. 返 回id号为 10102的Employee节点
  34. objNode = objDoc.SelectSingleNode(“Company/Department/Employees/Employee[@id=’10102’]”)
  35. b. 返回Name为Zhang Qi 的Name 节点
  36. objNode = objDoc.SelectSingleNode(“Company/Department/Employees/Employee/Name[text()=’Zhang Qi’]”)
  37. c. 返回部门含有职员22345的 部门名称节点
  38. objNode = objDoc.SelectSingleNode(“Company/Department[Employees/Employee/@id=‘22345’]/Department_Name”)
  39. 2.7 查询多重模式的节点
  40. 使用 | 符号可以获得多重模式的节 点。例如:
  41. objNodeList = objDoc.SelectNodes(“Company/Department/Department_Name | Company/Department/Manager”)
  42. 2.8 查询任意子节点
  43. 使用*符号可以返回当前节点的所有子节 点。
  44. objNodeList = objDoc.SelectNodes(“Company/*/Manager)
  45. 或者
  46. objNodeobjNodeList = objNode.ChildNodes
  47. 3 XML数据的编辑
  48. 3.1 增加一个元素的属性 (attribute)节点
  49. Dim objNodeAttr As XmlNode
  50. objNodeAttr = objDoc.CreateAttribute(“id”, Nothing)
  51. objNodeAttr.InnerXml = “101”
  52. objNode.Attributes.Append(objNodeAttr)
  53. 3.2 删除一个元素的属性
  54. objNode.Attributes.Remove(objNodeAttr)
  55. 3.3 增加一个子元素 (Element)
  56. Dim objNodeChild As XmlNode
  57. objNodeChild = objDoc.CreateElement(Nothing, “ID”, Nothing)
  58. objNodeChild.InnerXml = “101”
  59. objNode.AppendChild(objNodeChild)
  60. 3.4 删除一个子元素
  61. objNode.RemoveChild(objNodeChild)
  62. 3.5 替换一个子元素
  63. objNOde.ReplaceChild(newChild,oldChild)
  64. 4 参考数据
  65. <?xml version=“1.0” encoding=“UTF-8”?>
  66. <Company>
  67. <Department >
  68. <Department_Name>Cai WuBu</Department_Name>
  69. <Manager>Zhang Bin</Manager>
  70. <Employees>
  71. <Employee >
  72. <Employee_ID>12345</Employee_ID>
  73. <Name>Zhang Bin</Name>
  74. <Gender>male</Gender>
  75. </Employee>
  76. <Employee >
  77. <Employee_ID>10101</Employee_ID>
  78. <Name>Zhang QI</Name>
  79. <Gender>female</Gender>
  80. </Employee>
  81. <Employee >
  82. <Employee_ID>10102</Employee_ID>
  83. <Name>Zhang Xia</Name>
  84. <Gender>male</Gender>
  85. </Employee>
  86. <Employee >
  87. <Employee_ID>10201</Employee_ID>
  88. <Name>ZhangChuang</Name>
  89. <Gender>male</Gender>
  90. </Employee>
  91. <Employee >
  92. <Employee_ID>10202</Employee_ID>
  93. <Name>Zhang Jun</Name>
  94. <Gender>male</Gender>
  95. </Employee>
  96. </Employees>
  97. </Department>
  98. <Department >
  99. <Department_Name>KaiFa Bu</Department_Name>
  100. <Manager>Wang Bin</Manager>
  101. <Employees>
  102. <Employee >
  103. <Employee_ID>22345</Employee_ID>
  104. <Name>Wang Bin</Name>
  105. <Gender>male</Gender>
  106. </Employee>
  107. <Employee >
  108. <Employee_ID>20101</Employee_ID>
  109. <Name>Wang QI</Name>
  110. <Gender>female</Gender>
  111. </Employee>
  112. <Employee >
  113. <Employee_ID>20102</Employee_ID>
  114. <Name>Wang Xia</Name>
  115. <Gender>male</Gender>
  116. </Employee>
  117. <Employee >
  118. <Employee_ID>20201</Employee_ID>
  119. <Name>Wang Chuang</Name>
  120. <Gender>male</Gender>
  121. </Employee>
  122. <Employee >
  123. <Employee_ID>20201</Employee_ID>
  124. <Name>Wang Jun</Name>
  125. <Gender>male</Gender>
  126. </Employee>
  127. </Employees>
  128. </Department>
  129. </Company>

[转载]C#:XML操作类

mikel阅读(1012)

[转载]XML操作类(转) – rob_2010 – 博客园.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace PuTianCheng
{
/// <summary>
/// XmlHelper 的摘要说明
/// </summary>
public class XmlHelper
{
public XmlHelper()
{
}

/// <summary>
/// 读取数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”attribute”>属性名,非空时返回该属性值,否则返回串联值</param>
/// <returns>string</returns>
/**************************************************
* 使用示列:
* XmlHelper.Read(path, “/Node”, “”)
* XmlHelper.Read(path, “/Node/Element[@Attribute=’Name’]”, “Attribute”)
************************************************/
public static string Read(string path, string node, string attribute)
{
string value = “”;
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
value = (attribute.Equals(“”) ? xn.InnerText : xn.Attributes[attribute].Value);
}
catch { }
return value;
}

/// <summary>
/// 插入数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”element”>元素名,非空时插入新元素,否则在该元素中插入属性</param>
/// <param name=”attribute”>属性名,非空时插入该元素属性值,否则插入元素值</param>
/// <param name=”value”>值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Insert(path, “/Node”, “Element”, “”, “Value”)
* XmlHelper.Insert(path, “/Node”, “Element”, “Attribute”, “Value”)
* XmlHelper.Insert(path, “/Node”, “”, “Attribute”, “Value”)
************************************************/
public static void Insert(string path, string node, string element, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
if (element.Equals(“”))
{
if (!attribute.Equals(“”))
{
XmlElement xe = (XmlElement)xn;
xe.SetAttribute(attribute, value);
}
}
else
{
XmlElement xe = doc.CreateElement(element);
if (attribute.Equals(“”))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
xn.AppendChild(xe);
}
doc.Save(path);
}
catch { }
}

/// <summary>
/// 修改数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”attribute”>属性名,非空时修改该节点属性值,否则修改节点值</param>
/// <param name=”value”>值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Insert(path, “/Node”, “”, “Value”)
* XmlHelper.Insert(path, “/Node”, “Attribute”, “Value”)
************************************************/
public static void Update(string path, string node, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(“”))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
doc.Save(path);
}
catch { }
}

/// <summary>
/// 删除数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”attribute”>属性名,非空时删除该节点属性值,否则删除节点值</param>
/// <param name=”value”>值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Delete(path, “/Node”, “”)
* XmlHelper.Delete(path, “/Node”, “Attribute”)
************************************************/
public static void Delete(string path, string node, string attribute)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(“”))
xn.ParentNode.RemoveChild(xn);
else
xe.RemoveAttribute(attribute);
doc.Save(path);
}
catch { }
}
}
}

==================================================

XmlFile.xml:
<?xml version=”1.0″ encoding=”utf-8″?>
<Root />

==================================================

使用方法:

string xml = Server.MapPath(“XmlFile.xml”);
//插入元素
//XmlHelper.Insert(xml, “/Root”, “Studio”, “”, “”);
//插入元素/属性
//XmlHelper.Insert(xml, “/Root/Studio”, “Site”, “Name”, “小路工作室”);
//XmlHelper.Insert(xml, “/Root/Studio”, “Site”, “Name”, “丁香鱼工作室”);
//XmlHelper.Insert(xml, “/Root/Studio”, “Site”, “Name”, “谱天城工作室”);
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “Master”, “”, “红尘静思”);
//插入属性
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’小路工作室’]”, “”, “Url”, “http://www.wzlu.com/“);
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’丁香鱼工作室’]”, “”, “Url”, “http://www.luckfish.net/“);
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “”, “Url”, “http://www.putiancheng.com/“);
//修改元素值
//XmlHelper.Update(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]/Master”, “”, “RedDust”);
//修改属性值
//XmlHelper.Update(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “Url”, “http://www.putiancheng.net/“);
//XmlHelper.Update(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “Name”, “PuTianCheng Studio”);
// 读取元素值
//Response.Write(“<div>” + XmlHelper.Read(xml, “/Root/Studio/Site/Master”, “”) + “</div>”);
//读取属性值
//Response.Write(“<div>” + XmlHelper.Read(xml, “/Root/Studio/Site”, “Url”) + “</div>”);
// 读取特定属性值
//Response.Write(“<div>” + XmlHelper.Read(xml, “/Root/Studio/Site[@Name=’丁香鱼工作室’]”, “Url”) + “</div>”);
//删除属性
//XmlHelper.Delete(xml, “/Root/Studio/Site[@Name=’小路工作室’]”, “Url”);
//删除元素
//XmlHelper.Delete(xml, “/Root/Studio”, “”);

[转载]Flex全屏方法介绍

mikel阅读(1222)

[转载]Flex全屏方法介绍 – 镜涛的家 JT – 博客园.

最近在做工作流的流程设计工具相关的内容,web应用使用了比较标准的分布方式,即上、左、右的布局方式,这样做的结果就是设计工具的设计界面相对 较小,当遇到比较复杂的流程时就感觉设计的流程比较紧凑,设计工具的易用性不够好。为了解决这个问题,需要支持Flex的全屏模式。

想了下,可以通过以下方式实现Flex的全屏:

  1. 使用Flex的 FullScreen模式,具体实现方式为:
    1. 修改html- template文件夹下的index.template.html文件,在AC_FL_RunContent中增加:“allowFullScreen”, “true”;在embed中增加:allowFullScreen=”true”
    2. 通过设置stage.displayState 的值为 StageDisplayState.FULL_SCREEN来切换到全屏模式。

    缺点

    使用这种方式虽然能够将Flex切换到全屏模式,但是Flex中的InputText等 控件是无法编辑的,而且在Flex的中央会出现”Press Esc To Exist Full Screen”。因而这种方式无法满足设计需求。

    当然,中央出现的字幕还是有办法去掉的,虽然去掉之后并不能改变结果。去掉中央 的”Press Esc To Exist Full Screen”字幕的方法请见:

    http://stackoverflow.com/questions/1415436/flex-fullscreen-translate-edit-press-esc-to-exit-fullscreen-mode

    该文章讲解了去掉IE,Firefox中Flex全屏后字幕的方法。

  2. 通过showModalDialog来模拟Flex的全屏模式,showModalDialog中去掉工具栏、菜单栏、地址栏,同时将宽度 和高度设置成屏幕的宽度和高度。但是这种方式实现起来比较复杂,因为涉及到数据同步的问题,同步的方式根据项目的复杂程度和需求要求不同而不同。比较简单 的方式是在关闭showModalDialog时将数据同步主页面。因为这种方式实现复杂,容易出错,所以没有进行实现,有兴趣的朋友可以自己试试。
  3. 模拟IE的F11的全屏模式。当用户选择全屏模式的时候,模拟IE的F11 Press Down事件,隐藏掉IE的地址栏、菜单栏、工具栏等,同时将上部和左部的Frame隐藏掉,让右边的Frame全屏显示,达到预期的效果。

    IE的F11 PressDown 事件模拟方式实现如下:

    var shell = new ActiveXObject(‘WScript.Shell’)
    shell.SendKeys(‘{F11}’);

    Frame的隐藏方 法当然有很多,就不详细介绍了。

    缺 点

    这种方式需要用户修 改IE的安全选项,具体方法为:

    1. Tools > Internet options > Security > Custom Level
    2. ActiveX controls and plug-ins>Initializing and Script ActiveX controls not marked as safe>Enable

    如果没有将上面选项设置成Enable,那么会报:automation server can’t create object 错误。