T4文本模板

<#...#> 可以包含语句

<#=...#>  用于表达式,提供“输出”操作

<#+ ...> 使用类功能控制块向文本模板添加方法、属性、字段,必须作为文件中最后一个块显示

assembly 指令使指定的程序集可供模板代码使用,方式与 Visual Studio 项目中的“引用”部分相同。 您无需包括对 System.dll 的引用,它是自动引用的。 import 指令允许您使用类型而不使用其完全限定名,方式与普通程序文件中的 using 指令相同

若要从相对于文本模板的位置加载文件,可以使用 this.Host.ResolvePath()。 若要使用 this.Host,您必须在 template 中设置 hostspecific="true",还可以使用 this.Host.TemplateFile,它标识当前模板文件的名称。

如果已安装 Visual Studio 可视化和建模 SDK,则可以在每次执行生成时自动转换所有模板。 为此,可在文本编辑器中编辑项目文件(.csproj 或 .vbproj),然后在文件末尾附近(其他任何<import> 语句之后)添加以下行:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" />
<PropertyGroup>
   <TransformOnBuild>true</TransformOnBuild>
   <!-- Other properties can be inserted here -->
</PropertyGroup>

若要在 Visual Studio 错误窗口中放置错误消息和警告消息,可以使用以下方法:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#Error("An error message");#>
<#Warning("A warning message");#> 

类功能控制块是一个可以在其中定义辅助方法的块。 该块以 <#+...#> 分隔,并且必须作为文件中的最后一个块显示。

通过设置 <#@template#> 指令的 hostspecific 特性,可以允许模板获取对 Visual Studio API 的访问。 模板可以使用此功能获取项目文件的位置,以避免在模板代码中使用绝对文件路径。

一个读取XML的例子:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <catalog>
 3   <artist id ="Mike%20Nash" name="Mike Nash Quartet">
 4     <song id ="MikeNashJazzBeforeTeatime">Jazz Before Teatime</song>
 5     <song id ="MikeNashJazzAfterBreakfast">Jazz After Breakfast</song>
 6   </artist>
 7   <artist id ="Euan%20Garden" name="Euan Garden">
 8     <song id ="GardenScottishCountry">Scottish Country Garden</song>
 9   </artist>
10 </catalog>

  1 <#@ template debug="false" hostspecific="true" language="C#" #>
  2 <#@ output extension=".cs" #>
  3 <#@ assembly name="System.Xml" #>
  4 <#@ assembly name="EnvDTE" #>
  5 <#@ import namespace="System.Xml" #>
  6 <#@ import namespace="System.Collections.Generic" #>
  7 using System;
  8 using System.Collections.Generic;
  9 using System.Linq;
 10 using System.Xml;
 11 namespace MyProject
 12 {
 13 <#
 14  // Map node name --> child name --> child node type
 15  Dictionary<string, Dictionary<string, XmlNodeType>> nodeTypes = new Dictionary<string, Dictionary<string, XmlNodeType>>();
 16
 17  // The Visual Studio host, to get the local file path.
 18  EnvDTE.DTE dte = (EnvDTE.DTE) ((IServiceProvider) this.Host)
 19                        .GetService(typeof(EnvDTE.DTE));
 20  // Open the prototype document.
 21  XmlDocument doc = new XmlDocument();
 22  doc.Load(System.IO.Path.Combine(dte.ActiveDocument.Path, "exampleXml.xml"));
 23  // Inspect all the nodes in the document.
 24  // The example might contain many nodes of the same type,
 25  // so make a dictionary of node types and their children.
 26  foreach (XmlNode node in doc.SelectNodes("//*"))
 27  {
 28    Dictionary<string, XmlNodeType> subs = null;
 29    if (!nodeTypes.TryGetValue(node.Name, out subs))
 30    {
 31      subs = new Dictionary<string, XmlNodeType>();
 32      nodeTypes.Add(node.Name, subs);
 33    }
 34    foreach (XmlNode child in node.ChildNodes)
 35    {
 36      subs[child.Name] = child.NodeType;
 37    }
 38    foreach (XmlNode child in node.Attributes)
 39    {
 40      subs[child.Name] = child.NodeType;
 41    }
 42  }
 43  // Generate a class for each node type.
 44  foreach (string className in nodeTypes.Keys)
 45  {
 46     // Capitalize the first character of the name.
 47 #>
 48     partial class <#= UpperInitial(className) #>
 49     {
 50       private XmlNode thisNode;
 51       public <#= UpperInitial(className) #>(XmlNode node)
 52       { thisNode = node; }
 53
 54 <#
 55     // Generate a property for each child.
 56     foreach (string childName in nodeTypes[className].Keys)
 57     {
 58       // Allow for different types of child.
 59       switch (nodeTypes[className][childName])
 60       {
 61          // Child nodes:
 62          case XmlNodeType.Element:
 63 #>
 64       public IEnumerable<<#=UpperInitial(childName)#>><#=UpperInitial(childName) #>
 65       {
 66         get
 67         {
 68            foreach (XmlNode node in
 69                 thisNode.SelectNodes("<#=childName#>"))
 70              yield return new <#=UpperInitial(childName)#>(node);
 71       } }
 72 <#
 73          break;
 74          // Child attributes:
 75          case XmlNodeType.Attribute:
 76 #>
 77       public string <#=childName #>
 78       { get { return thisNode.Attributes["<#=childName#>"].Value; } }
 79 <#
 80          break;
 81          // Plain text:
 82          case XmlNodeType.Text:
 83 #>
 84       public string Text  { get { return thisNode.InnerText; } }
 85 <#
 86          break;
 87        } // switch
 88      } // foreach class child
 89   // End of the generated class:
 90 #>
 91    }
 92 <#
 93  } // foreach class
 94
 95    // Add a constructor for the root class
 96    // that accepts an XML filename.
 97    string rootClassName = doc.SelectSingleNode("*").Name;
 98 #>
 99    partial class <#= UpperInitial(rootClassName) #>
100    {
101       public <#= UpperInitial(rootClassName) #>(string fileName)
102       {
103         XmlDocument doc = new XmlDocument();
104         doc.Load(fileName);
105         thisNode = doc.SelectSingleNode("<#=rootClassName#>");
106       }
107    }
108 }
109 <#+
110    private string UpperInitial(string name)
111    {
112       return name[0].ToString().ToUpperInvariant() + name.Substring(1);
113    }
114 #>

时间: 2024-08-28 18:16:40

T4文本模板的相关文章

T4文本模板转换过程

T4文本模板转换过程将文本模板文件作为输入,生成一个新的文本文件作为输出. 例如,可以使用文本模板生成 Visual Basic 或 C# 代码,还可以生成 HTML 报告. 有三个组件参与这一过程:引擎.宿主和指令处理器. 引擎对该过程进行控制(引擎与宿主和指令处理器交互),以生成输出文件:宿主提供与环境的所有交互(如定位文件和程序集); 指令处理器为文本模板添加功能(如从 XML 文件或数据库读取数据等). 组件: 组件 说明 可自定义(是/否) 引擎 引擎组件控制文本模板转换过程. 否 主

一个简单的代码生成器(T4文本模板运用)

说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了.今天痛定思痛,终于把这件拖了很久的事做了.好,不废话了,现在看看"一个简单的代码生成器" . 先看看界面吧! 简约到如此,说是代码生成器,估计是要被吐槽的.好吧,借用园子里博友的说法,这只是一粒粟子,如果你愿意,你能看到代码生成器的"种子". 这样运行的! 画了个简图已描述这个简单的代码生成器的工作过程.下面的介绍将以此图展开: 1)读取数据表的信息:从数据库中读取数据表的

编写 T4 文本模板

文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板处理方式的元素,为模板转换引擎提供说明. T4文本模板指令包括:    T4模板指令:  T4参数指令:  T4输出指令:  T4程序集指令:  T4导入指令:  T4包含指令:  T4 CleanUpBehavior 指令及其自定义指令. 指令的语法如下所示: <#@ DirectiveName

C#代码生成工具:文本模板初体验 使用T4批量修改实体框架(Entity Framework)的类名

转自:http://www.cnblogs.com/huangcong/archive/2011/07/20/1931107.html 在之前的文本模板(T4)初体验中我们已经知道了T4的用处,下面就看看如何用它来实现批量修改实体框架(Entity Framework)中的类名.我们都知道ADO.NET 实体数据模型中有一种方式是以数据库模型来生成数据模型的,这是个很简便的实体数据模型生成的方式,但是因为微软提供的自定义接口不足,我们无法实现对生成的数据模型实体类批量进行修改(至少我上网找了很久

T4模板之文本模板

网址:https://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-text-templates?view=vs-2017 T4模板在平时我们其实都会或多或少的遇到.最多的用在实体与数据库的映射上面. 这里只记录一下他的语法. 需要的插件:vs2017 T4代码高亮插件:Devart T4 Editor T4生成多文件:T4 Toolbox  (使用这个可以很好的生成我

关于C#中文本模板(.tt)的简单应用

转自http://www.it165.net/pro/html/201409/21789.html 这两天做项目突遇 .tt文件,之前没有接触过,so查询学习做笔记,帮助记忆和后来者. 在项目添加中点击选择文本模板 下面贴出代码,做了简单的注释 01.<#@ template debug="false" hostspecific="false" language="C#" #> 02.<#@ assembly name=&quo

JSON、文本模板、HTML模板

JSON JSON是一种发送和接收格式化信息的标准.JSON不是唯一的标准,XML.ASN.1 和 Google 的 Protocol Buffer 都是相似的标准.Go通过标准库 encoding/json.encoding/xml.encoding/asn1 和其他的库对这些格式的编码和解码提供了非常好的支持,这些库都拥有相同的API. 序列化输出 首先定义一组数据: type Movie struct { Title string Year int `json:"released"

T4模板:T4模板之菜鸟篇

一.废话 T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎.在 Visual Studio 中,"T4 文本模板"是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件. 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段.生成的文件可以是任何类型的文本,例如网页.资源文件或任何语言的程序源代码.现在的VS中只要与代码生成相关的场景基本上都能找T

T4模板:T4模板之基础篇

一.回顾 上一篇文章 --T4模板之菜菜鸟篇,我们囫囵吞枣的创建了与"T4模板"有关的文件.在创建各个文件的这一个过程中,我们对于T4模板有了那么丁点的认识.现在就带着之前的那些问题,正式的迈入对"T4模板"的学习. 二.概念 2.1.类型 T4 文本模板有两种类型: 设计时 T4 文本模板 运行时 T4 文本模板 三.简要教程 我们只讲"设计时T4文本模板",其他的都TMD属于高级部分了,哥不懂给不给? 打开之前我们创建的"TextT