首页 > 其他 > 详细

T4文本模板

时间:2015-05-08 12:52:26      阅读:193      评论:0      收藏:0      [点我收藏+]

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

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

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

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>
View Code
技术分享
  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 #>
View Code

 

T4文本模板

原文:http://www.cnblogs.com/goodlucklzq/p/4422765.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!