首頁

2013年8月29日 星期四

**(技巧)善用CODE-可透過程式來執行~T4範本喔**아 ~ T4 템플릿을 통해 실행하는 ** (기술) 코드 사용 프로그램**

***(技巧)善用CODE-可透過程式來執行~T4範本喔***
*KR* ~ T4 템플릿을 통해 실행하는 ** (기술) 코드 사용 프로그램 ****

**典型T4應用多發生於專案編輯階段,透過存檔動作或PowerShell Script產生程式碼。
簡單嘗試後,發現T4早已設想周到,在程式中用T4產生文字是小菜一碟, 
透過Runtime Text Template(執行階段文字範本)即可輕鬆達成, MSDN有篇---
---詳細說明可以參考      **
*KR**일반적인 응용 프로그램은 행동이나 PowerShell 스크립트 아카이브 생성 코드를 통해, 프로젝트 T4 편집 단계에서 발생했습니다. 간단한 시도는, 사려 깊은 T4, T4 프로그램 텍스트 런타임 텍스트 템플릿 (런타임 텍스트 템플릿)를 통해, 케이크의 조각을 사용하여 생성 쉽게 접근 할 ​​수, MSDN 자세한 설명 문서를 참조 수 있습니다 발견했다                   

**一個簡單範例,從PTT取得文章清單後,透過T4輸出成文字檔。
首先,在專案中新增一個Runtime Text Template: (在General分類下,直接用關鍵字"template"過濾比較快)                 **
**간단한 예를 들어, T4를 통해 텍스트 파일로 출력 한 후 PTT 만든 기사 목록입니다  **
**첫째, 런타임 텍스트 템플릿을 추가하는 프로젝트 (일반 범주에서 직접 사용 키워드 
"템플릿"필터 빠릅니다)                               **
****
**傳統T4範本不同,每個Runtime T4範本都附加了同名的cs檔案,定義同名的---
---類別物件(在本例中RTT4.tt範本,對應的類別名稱即為RTT4),便可在程式碼中
建立範本物件RTT4,呼叫其.TransformText()方法就能獲得轉換結果                                    **기존의 T4 템플릿이 다른 런타임 T4 템플릿 cs 파일 같은 이름, 클래스 개체 정의  
(이 경우 RTT4.tt 템플릿을 해당 범주 이름 RTT4입니다)과 동일한 이름을 가진 연결되어, 당신은 코드에서 템플릿을 만들 수 있습니다 객체 RTT4, 그 호출합니다.  
TransformText () 메소드가 변환 결과를 얻을 수 있습니다                                     **

****
**Runtime T4時,呼叫端常需傳遞參數物件給T4範本,以達到動態變更產生內容的彈性。
要實現此點,可透過T4類別為partial class的特性,在專案另外加入類別名稱相同---
---partial class檔案(即上圖中的RTT4Code.cs),於其中另外定義內部欄位、屬性,
並透過建構式接收參數。
範例先要定義文章資料物件:                                   *
*KR**런타임 T4, 호출자는 종종 유연성을 달성하기 위해 변경하는 동적으로 내용을 
생성하는 T4 템플릿에 매개 변수 개체를 전달해야합니다. 또한 내부 필드, 속성 
통해서 구성 주의적 정의하는 같은 이름의 partial 클래스 파일  
 (예 : RTT4Code.cs 위의 그림)를 클래스에 추가하여 프로젝트의 T4 카테고리 
partial 클래스 속성을 통해이를 달성하기 위해 수신기 매개 변수입니다.
첫 번째 예는 데이터 객체를 정의                             *
**
public class Post
    {
        public string Date;
        public string Author;
        public string Subject;                                *
*KR*공용 클래스  {공공 문자열 날짜, 공공 문자열 저자, 공공 문자열 제목;           **
 
**在partial class加入接收List<Post>的建構式,並宣告一個內部欄位posts,用以儲存文章清單      **
*KR*
목록 <Post>받는 부분 클래스 생성자에 참여하고, 기사의 목록을 저장하는 데 사용되는 내부 필드 포스트를 선언**
 
*
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace RuntimeT4
{
    partial class RTT4
    {
        private List<Post> posts;
        public RTT4(List<Post> posts)
        {
            this.posts = posts;
        }
    }
}                                                                           *
**KR**
시스템을 사용하여, System.Collections.Generic 사용하여, System.Linq에 사용하기; 
 System.Text 사용하여, 네임 스페이스 RuntimeT4 {partial 클래스 RTT4  
{개인 목록 <Post> 게시물, 
공공 RTT4 (목록 <Post> 게시물) {this.posts = ; }}}                        *
 
**T4範本如下,注意其中的this.posts,就是我們在partial class中所定義的內部欄位**
**아래 T4 템플릿은 예고  this.posts, partial 클래스에서 우리가 정의하는 내부 필드의**
*
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<# 
int i = 1;
foreach (var p in this.posts) 
{ #>
<#= i++ #>.<#= p.Date #> / <#= p.Author #> / <#= p.Subject #>
<# } #>                                       *
**KR**<# @ 템플릿 언어 = "C #"#> <# @ 어셈블리 이름 = "System.Core에"#> 
<# @ 가져 오기 네임 스페이스 = "System.Linq에"#> <# @ 가져 오기 네임 스페이스 =
 "System.Text"#> <# @ 가져 오기 네임 스페이스 = "System.Collections.Generic"#> 
<# int 전 = 1; foreach는 (this.posts VAR P) {#>. <# = I + + #> <# = p.Date #> / <# =
 p.Author #> / <# = p.Subject #> <#} #>                                                *
 
**
呼叫端程式如下(結果抓資料部分比主體多出許多 orz),它會抓回PTT笨版第一頁,
從HTML取出文章列表交由RTT4範本執行,
.TransformText()後可得到一個字串,即為產出結果                                       *
*KR*
(결과  ORZ보다 많은 기본 데이터 부분을 잡고)는 다음과 같이 프로그램을 호출, 
그것이 RTT4 HTML 템플릿을 실행하여 문서 목록에서 첫 번째 페이지 캡처 PTT 바보 버전을 제거합니다. 
 TransformText ()는 문자열 뒤에 얻을 
수 있습니다 결과가 출력됩니다                  
*class Program
    {
        static void Main(string[] args)
        {
            //連上PTT網站取回文章資料
              List<Post> posts = GetPTTPosts();
            
            //將文章資料當成參數傳給T4
            RTT4 t = new RTT4(posts);
            //執行TransformText()即可取得結果
    Console.WriteLine(t.TransformText());
            Console.Read();
        }
        //取得PTT文章清單
        static List<Post> GetPTTPosts()
        {
            WebClient wc = new WebClient();
            wc.Encoding = Encoding.GetEncoding(950);
            string h = wc.DownloadString(
                "http://www.ptt.cc/bbs/StupidClown/index1.html");
            List<Post> posts = new List<Post>();
            string date = null, author = null, subject = null;
            Regex re = new Regex(">(?<t>[^<]+?)<");
            Func<string, string> getInnerText = 
                s => re.Match(s).Groups["t"].Value;
            foreach (string line in h.Split('\n'))
            {
                if (line.StartsWith("<td width=\"50\">"))
                    date = getInnerText(line);
                else if (line.StartsWith("<td width=\"120\">"))
                    author = getInnerText(line);
                else if (line.StartsWith("<td width=\"500\">"))
                {
                    subject = getInnerText(line);
                    posts.Add(new Post()
                    {
                        Date = date,
                        Author = author,
                        Subject = subject
                    });
                }
 
            }
            return posts;
        }                                                            *

**
클래스 프로그램 {정적 무효 메인 (문자열 [] args) {/ / 连 上 PTT 网站 取回 文章 资料 
목록 <Post>  = GetPTTPosts () / / 将 文章 资料 当成 参数 传给 T4 RTT4 t = 
새로운 RTT4 (게시물 ) / / 执行 TransformText () 即可 取得 结果 Console.WriteLine으로 
(t.TransformText ()); Console.Read (); WebClient를} / / 取得 PTT 文章 清单 정적 목록 
 <Post> GetPTTPosts () {WebClient를 화장실 = 새로운 () wc.Encoding = 
 Encoding.GetEncoding (950) 문자열 H = wc.DownloadString 
( "http://www.ptt.cc/bbs/StupidClown/index1.html"); 목록 <Post> 게시물 =
 새로운 목록 <Post> () 문자열을 날짜 = NULL, 저자 = NULL, 주제 = NULL; 정규식  = 
 정규식 ( "> (<T> [^ <] +) <??"); Func을 <string, 스트링 getInnerText = S => 
 re.Match (들) 그룹 [ "t"] ;.. foreach는 (h.Split ( '\ N')의 문자열 라인)  
{(line.StartsWith ( "<TD  = \"50 경우 \ ">")) 날짜 = getInnerText (라인), 
 다른 사람 (line.StartsWith ( "<td width=\"120\">")) 저자 = getInnerText (라인), 
 다른 사람 (line.StartsWith ( "< TD  = \ "500 \"> ")) {대상 = getInnerText (라인), 
 posts.Add (새 포스트 () {날짜 = 날짜, 저자 = 저자,클래스 프로그램 {정적 무효 메인  
(문자열 [] args) {/ / 连 上 PTT 网站 取回 文章 资料 목록 <Post>  = GetPTTPosts ()  
/ / 将 文章 资料 当成 参数 传给 T4 RTT4 t = 새로운 RTT4 (게시물 ) / / 执行 TransformText  
() 即可 取得 结果 Console.WriteLine으로 (t.TransformText ()); Console.Read (); WebClient를} 
 / / 取得 PTT 文章 清单 정적 목록 <Post> GetPTTPosts () {WebClient를 화장실 = 새로운 
 () wc.Encoding = Encoding.GetEncoding (950) 문자열 H = wc.DownloadString  
( "http://www.ptt.cc/bbs/StupidClown/index1.html"); 목록 <Post> 게시물 = 
 새로운 목록 <Post> () 문자열을 날짜 = NULL, 저자 = NULL, 주제 = NULL; 정규식  = 
 정규식 ( "> (<T> [^ <] +) <??"); Func을 <string, 스트링 getInnerText = S =>  
re.Match (들) 그룹 [ "t"] ;.. foreach는 (h.Split ( '\ N')의 문자열 라인)  
{(line.StartsWith ( "<TD  = \"50 경우 \ ">")) 날짜 = getInnerText (라인),
 다른 사람 (line.StartsWith ( "<td width=\"120\">")) 저자 = getInnerText (라인),
 다른 사람 (line.StartsWith ( "< TD  = \ "500 \"> ")) {대상 = getInnerText (라인),
 posts.Add (새 포스트 () {날짜 = 날짜, 저자 = 저자, 
 제목 = 대상});}} 반환 게시물;} 제목 = 대상});}} 반환 게시물;}                        *
**執行結果:       *
**집행 결과 :         
*
1. 4/23 / vivianJ / 我大概是唯一一個被"阿"過的女生吧
2. 4/25 / purinfocus / 小護士回憶錄2
3. 4/27 / EchoMary / 話說今天期中考..
4. 5/05 / wubaiwife / 是任性還是笨﹖
5. 5/22 / m0630821 / [閒聊] 油表上的E是?
6. 6/13 / hohoholalala / 去郵局
7. 6/22 / cynthia730 / 語無倫次
8. 6/22 / chachalee / 你真的是我媽嗎?
9. 6/25 / superlubu / [動畫] 三人成虎大鬧台北第七集  慘劇
10. 8/04 / keikolin / [耍笨] 我終於當媽了
11. 8/05 / utou / [動畫]笨蛋的故事
12. 9/12 / okaoka0709 / [轉錄]Re: [火大] 我的姓真的很特別嗎
13. 9/25 / Liska / [童年] 中秋節烤肉= =|||
14.10/03 / JKH945 / [生日+笨夢] 19歲最後一個夢
15.10/28 / winniechi / [耍笨] 類疊的用法
16.11/10 / olivetrees / 我弟應該算是最早的詐騙集團
17.11/10 / keikoYAMADA / 古蹟修護系
18.12/12 / glenmarlboro / 突然想到一件笨事
19.12/14 / QQQWERT / [耍笨] 其實...應該很多人做過這種事
20.12/18 / Chucky9527 / [耍笨] 我的朋友的褲子拉鍊忘了關                   *
*1. 23분의 4 / vivianJ / 아마 "A"여자, 잘 될 수있는 유일한 사람이야2. 25분의 4 / purinfocus / 간호사 회고록 23. 27분의 4 / EchoMary / 토크 오늘 중간 고사 ..4. 5월 5일 / wubaiwife / 고의 또는 바보입니까?5. 22분의 5 / m0630821 / [채팅] 오일 E 테이블에 무엇입니까?우체국 6. 13분의 6 / hohoholalala /7. 22분의 6 / cynthia730 / 조리8. 22분의 6 / chachalee / 당신은 정말 내 어머니가 어떻게 있습니까?9. 25분의 6 / superlubu / [동영상] 타이거  타이페이 세븐 비극 10. 8 / 04 / keikolin / [바보 재생] 나는 마지막 의 어머니11. 8 / 05 / utou / [애니메이션] 바보의 이야기12 9 / 12 / okaoka0709 / [전사] 재 :. [] 내 마지막 이름은 정말 특별한 당신13. 25분의 9 / LISKA / [아동] 중추절 바베큐 == | | |14.10/03 / JKH945 / [생일 + 바보의 꿈] 마지막  십구년15.10/28 / winniechi / [바보 재생] 클래스 스택 사용16.11/10 / olivetrees / 내 동생 가장 오래된 사기로 간주되어야한다17.11/10 / keikoYAMADA / 유서 복구 시스템18.12/12 / glenmarlboro / 갑자기 멍청한 생각19.12/14 / QQQWERT / 사실 [바보 재생]는 ... 많은 사람들이 그런 일을했을이어야한다20.12/18 / Chucky9527 / [바보 재생] 내 친구 바지 지퍼를 해제하는 것을 잊었다                              *
 
*學會這招,就能在自己的程式中輕鬆使用T4生Code,以後就不必用StringBuilder硬兜囉!*
*이 트릭 배웠습니다, ​​당신은 쉽게 T4 원시 코드 사용하여 자신 프로그래밍 할 수 있습니다,
 ​​안녕하세요 모두 StringBuilder 하드 주머니를 사용하지 않습니다!**
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&