トップ   差分 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

  • 追加された行はこの色です。
  • 削除された行はこの色です。
  • XML2dev2 へ行く。

#freeze
[[XMLに手を出した>XML0]]~
**[[おぼえがき・その2>XML2dev2]] [#sc9c455f]

#contents
----
SIZE(10){今更だけど.Net Framework2.0}~
SIZE(10){モバイルWEBフォームとかあるのに不便。}~
----

**ケータイでみれないぉ!(・∀・) [#v07d8cc7]
自分でサイト作るとこういうとこがもう…ね…~
~
フィルター(この場合スキンやテンプレートみたいなイメージ)とやらで一発変換できないのけ!~
~
とかまず思う。いろいろ調べてみたけど…ないな。そんな便利機能。~
便利ツールは自分で実装しなきゃいけないみたいだ。~
~
まずは出力をShift-Jisにしないとな…~
streamとかでshift-jisで吐き出すとか手はあるだろうけど~
それならweb.configで設定して…結局別仮想ディレクトリかいな。~
ということで昔懐かしいUserAgentで判別ロジックを組んでPCサイトからリダイレクトを実装。~
ケータイ用サイトに飛ぶようにする。~
~
~
でもこれじゃぁケータイ用サイトをまた作るって手間になるなぁ。~
便利ツール(頭の中にだけあるケータイ向け便利スクリプト)を~
既存masterファイルに噛ませてなんとかならないかな〜。~
~
…とか考えるときっとこうなる。
 <%if%>
   PC用
 <%else%>
   ケータイ用
 <%endif%>
…きっとこれじゃ(マイクロソフトのvisualなんたら製品で)デザイナ画面が見れない。~
(私的サイトなんだし(?)デザイナ見ながら作業したいよ。)~
~
~
**ケータイでみれないぉ!(・∀・)その2 [#if2e8914]
便利ツール(頭の中にだけあるケータイ向け便利スクリプト)を考えてみよう。~
・UserAgent判別。~
・おそらくケータイ向けテンプレ(masterでもいいしテキストベースでもいい)を読み込む~
・モバイルWEBページにリダイレクトとかもあり?~
・既存(PC向け)コンテンツがUTF-8なためShift-JisによるStreamWriter必須。~
~
テンプレは…ハッ(゚д゚)XSLでいいのか?!~
~
~
~
**便利でもないツールをつくってみた。 [#hb865af4]
参考は[[ココ>http://ufcpp.net/study/aspx/blog1.html]]
~
流れとしては~
 トップページ.aspxでUserAgent判別
 ↓          ↓
 (PC)        (ケータイ)
 そのまま表示    ケータイ.aspx(便利ツールのつもり)へリダイレクト
            ↓
           テキストファイル(XML)を読み込んでHTMLへ変換(XSL)してShiftJisで出力

~
~
諸事情によりコードファイルで実現できないので共通っぽいのは~
懐かしいIncludeで読み込ませる。~
トップページ.aspx
 <%@ Page Language="C#" ・・・%>
 
 <script runat="server">
     public string mobfile = "ケータイ.aspx"; 
 </script>
 <!--#include file="判別用スクリプト.inc"-->
 
 <!DOCTYPE ・・・・>
 <html ・・・>

とりあえずトップページだけでも対応するってことで~
判別用スクリプト内でケータイ.aspxへリダイレクト。~
判別用スクリプトはこんだけ。IT@MEDIAの記事を参考。(いらないコードも入ってるな…)
 <script runat="server">
     private readonly static string[] MobileUserAgentList = new string[]{
         "(DoCoMo){1}",
         "(UP.Browser){1}",
         "(J-PHONE){1}",
         "(Vodafone){1}",
         "(SoftBank){1}"
     };
 
     protected bool isMobile(string[] agentInfo)
     {
         foreach (string usr in agentInfo)
         {
             foreach (string exp in MobileUserAgentList)
             {
                 if (Regex.IsMatch(usr, exp))
                 {
                     return true;
                 }
             }
         }
         return false;
     }
 
     protected new void Page_Load(object sender, System.EventArgs e)
     {
         string[] agentInfo = HttpContext.Current.Request.UserAgent.Split('/');
         if (agentInfo.Length == 0)
         {
 
         }
         else
         {
             if (isMobile(agentInfo))
             {
                 Server.Transfer(mobfile);
             }
         }
     }
 </script>
作りやすいのでこの判別スクリプトもaspxファイルにしてたけど~
mobfile(トップページ.aspxで指定したケータイ用ファイル)のスコープエラーとか~
PageLoadはnewいらないとかいるとかいろいろ出るので.incとかにしてみた。~
SIZE(10){ウチのマシン性能のせいかもしれんケドね…デバッグ情報が少し遅い。}~
COLOR(#c4a8de){PageLoad にnewが必要なのはコードファイル側にすでにPageLoadがあったからっぽい…。}~
~
そしていよいよ!~
のちのちこれが便利ツール本体になるはずの!~
ケータイ.aspx
 <%@ Page Language="C#" %>
 <%@ Import Namespace="System.IO" %>
 <%@ Import Namespace="System.Text" %>
 <%@ Import Namespace="System.Xml" %>
 <%@ Import Namespace="System.Xml.Xsl" %>
 <%@ Import Namespace="System.Xml.XPath" %>
 <script runat="server">
     //------------------------------------------------
     //PageLoadでなくPage_PreRenderってところがミソらしい
     //------------------------------------------------
     protected void Page_PreRender(object sender, System.EventArgs e)
     {
         //--------------------------
         //XML(テキスト)をXSLでhtmlに変換
         //--------------------------
         // ファイルを取得するには相対パスじゃだめらしい。
         string xfpath = Context.Server.MapPath("~/データディレクトリ");
         string xspath = Context.Server.MapPath("~/xslが置いてあるディレクトリ");
         string xmlfile = xfpath + "/データ.xml";
         string xslfile = xspath + "/スタイル.xsl";
         
         //XMLを読み込む
         XmlDocument myXMLDoc = new XmlDocument();
         myXMLDoc.Load(xmlfile);
         //XSLTを変換用に読み込む
         XslCompiledTransform transformer = new XslCompiledTransform();
         transformer.Load(xslfile);
         
         //読み込んだXMLのリーダーを生成
         XmlNodeReader reader = new XmlNodeReader(myXMLDoc);
         //変換するためのメモリ領域生成
         MemoryStream xs = new MemoryStream();
         //変換するためのライター生成
         // * ちなみにxmlもxslもShift-Jisで作ったが
         // * ここのエンコードはデフォ(UniCode?UTF-8?で。)
         XmlTextWriter xw = new XmlTextWriter(xs, null);
         
         //いざ!変換。リーダーをライターへ。
         transformer.Transform(reader, xw);
         
         //------------------------
         //Responseするための準備
         //------------------------
         //変換した中身を読み込む
         xs.Seek(0, SeekOrigin.Begin);
         StreamReader xr = new StreamReader(xs);
         string outXhtm = xr.ReadToEnd();
         xs.Dispose();
         
         //Reasponseライター生成。ここでエンコードをShift−Jisへ。
         Encoding enc = Encoding.GetEncoding("shift_jis");
         Stream stream = Response.OutputStream;
         StreamWriter writer = new System.IO.StreamWriter(stream, enc);
         writer.Write(outXhtm);
         writer.Flush();
         
     }
 </script>
中身はこんだけ。~
XML→XSL変換でShift-Jisにしたら二重変換みたいになった。~
…データファイルやなんやはデフォで作ってもいいのかもしれんな…。~
COLOR(#c4a8de){↑コード中のコメントに「xslもshift-jis」と書いてあるがutf-8のものもあった…}~
COLOR(#c4a8de){↑…xmlはshift-jisだったり(´・ω・)混在モード…}~
COLOR(#c4a8de){↑それで文字化けしてたのかもなぁ。最後のwriterがshift-jisで出してるから問題ナイっぽい。}~
~
~
~
**リダイレクト無しで・・・ [#ec137209]
というわけで、記事部分をXMLで、XSLはHTMLにするために通す。~
トップページの記事xmlとxslを設定。~
ケータイ.aspx→ケータイ.incにして<%@ Page ・・・%>を消す。~
トップページ.aspx
 <%@ Page ・・・ %>
 <script runat="server">
     public string myXmlpath = "~/データディレクトリ";
     public string myXslpath = "~/xslの置いてあるディレクトリ";
     public string myXml = "/記事.xml";
     public string myXsl = "/ケータイ用変換.xsl";
 </script>
 <!--#include file="判別用スクリプト.inc"-->
 <!--#include file="ケータイ.inc"-->
 
 <!DOCTYPE html ・・・>
 
 <html xmlns="http://www.w3.org/1999/xhtml" >
 :
 (以下通常ページの記述)
~
ケータイ.incのPage_PreRenderをシリアル化…(?というんだろうか)~
COLOR(#c4a8de){↓リダイレクト無しの場合、Page_Loadでケータイ判別〜その後処理〜レスポンスで終了。}~
COLOR(#c4a8de){↓つまりケータイの時はPage_Loadで終了させたい。}~
Page_PreRrenderはwebアプリがページを表示する時のイベントなのでオリジナルのメソッドにする。~
(つまり通常のイベントと被らないようにメソッド名を変更。この際なんでもいい。)
      protected void myPage_PreRender(object sender, System.EventArgs e)
      {
        :

ファイルパス取得のところを書き換え。~
ケータイ.inc読み込み前にセットしてある変数を参照る。
         //--------------------------
         //XML(テキスト)をXSLでhtmlに変換
         //--------------------------
         // ファイルを取得するには相対パスじゃだめらしい
         string xfpath = Context.Server.MapPath(myXmlpath);
         string xspath = Context.Server.MapPath(myXslpath);
         string xmlfile = xfpath + myXml;
         string xslfile = xspath + myXsl;
~
ケータイ.incのwriter.Flush()の後にレスポンス用の処理コードを追加。~
COLOR(#c4a8de){↓これでケータイの時はPage_Loadイベントでhttpレスポンス終了になる。}~
         this.Response.HeaderEncoding = enc;
         this.Response.ContentType = "text/html; charset=Shift_JIS";
         this.Response.Flush();
         this.Response.End();
レスポンス終了!~
SIZE(10){ContentTypeのcharsetがShift_JISが正しいのかShift-JISが正しいのか…}~
これでトップページ.aspxに書かれているWEB.UIのレスポンスを抑止。~
~
~
判別用スクリプト.incのリダイレクトをmyPage_PreRender呼び出しに書き換え。
     protected new void Page_Load(object sender, System.EventArgs e)
     {
         :
              if (isMobile(agentInfo))
              {
                  //Server.Transfer(mobfile);
                  myPage_PreRender(sender, e);
              }
         :
     }
~
…いちおできたけど…
記事.xmlのバッファ長とか改良点はありそうなかんじ(′・ω・`)~
~
~
**Masterファイルを使っていたので・・・ [#db75c3e2]
aspxの各ページはMasterファイル使ってデザインを統一している。~
デザインの基本は:~
・レイアウトはMasterに書いたとおり~
・色、背景画像はPage_LoadでMasterにcssを追加する形で実現~
~
…Page_Load(´・ω・)~
いざ携帯に変換しようとしたら判別スクリプト(判別.inc)はPage_Loadに書かれていた…。~
ので判別はPage_PreRenderイベントで行うようにした。~
 <script runat="server">
  : 
     protected new void Page_PreRender(object sender, System.EventArgs e)
     {
         string[] agentInfo = HttpContext.Current.Request.UserAgent.Split('/');
         if (agentInfo.Length == 0)
         {
 
         }
         else
         {
             if (isMobile(agentInfo))
             {
                  myPage_PreRender(sender, e);
             }
         }
     }
 </script>
…元々Page_PreRenderでやるべきところだったんだもんな〜~
ってコトで問題なし(・∀・)…のハズ。~
COLOR(#c4a8de){↑newが付いてるのは…うpするサーバーではdllとか使えないんだけどローカルではコンパイルできるから〜。どちでも使えるようにしてみただけ。}~
~
~
**Masterファイルを使っていたので・・・(その2) [#p2502650]
MasterType使ってmasterにオーバーライドしてるaspxで巧く変換されないぉ!(・∀・)~
…ってことでmasterにケータイ用スクリプト埋めることにする…~
COLOR(#c4a8de){↑試していたファイルパス不正でtry〜catchしたのにthrowしてなかっただけかもだが今となってはわからん…}~
masterにケータイ変換用変数のget/setアクセサを実装…~
 
     protected string myXmlpath = "~/データディレクトリ";
     protected string myXslpath = "~/xslの置いてあるディレクトリ";
     protected string myXml = "/記事.xml";
     protected string myXsl = "/ケータイ用変換.xsl";
     public string MobXmlPath
     {
          get{return myXmlpath;}
          set{myXmlpath = value;}
     }
         :
       (以下同じようにオナジ用に宣言)
 
…面倒なのでこれも別ファイル化。(ケータイ用変数.inc)
masterにinclude
 <%@ Master ・・・ %>
 <%@ Import namespase="System.Web.UI.WebControls" %>
       :
     (import部分)
       :
 <script runat="server">
     // Masterのweb.ui.contorolに対して上書きするためのアクセサ
     public string テキストラベル
     {
            get { return this.Label1.Text; }
            set { this.Label1.Text = value; }
     }
         :
 </script>
 <!--#include file="ケータイ用変数.inc"-->
 <!--#include file="判別用スクリプト.inc"-->
 <!--#include file="ケータイ.inc"-->
 <script runat="server">
     // MasterのPage_Load処理(通常=PC表示時の処理)
     protected new void Page_Load(object sender, System.EventArgs e)
     {
         :
     }
 </script>
 
 <!DOCTYPE html ・・・>
 
 <html xmlns="http://www.w3.org/1999/xhtml" >
 :
 (以下通常masterページの記述)
 
このmasterを使うaspxの記述
  <%@ Page … %>
  <%@ MasterType … %> 
  <script runat="server">
  protected new void Page_Load(object sender, System.EventArgs e)
  {
      Master.MobXmlpath = "~/App_Data/x_heavnsdoor";
      Master.MobXslpath = "~/x_heavnsdoor/css";
      Master.MobXml = "/description.xml";
      Master.MobXsl = "/m_x_heavns.xsl";
      // 通常(=PC)用の変数もセット
      Master.テキストラベル = "PC用の変えたいテキストはココ";
         :
  }
 </script>
 :
 (以下通常ページの記述)
  
これでなんかスッキリ(・∀・)~
だけどイベント処理的にこれでいいのかな〜(´・ω・)とか思ってしまう~
aspxの方がPage_Loadでmasterの方がPage_PreRenderっていう。~
MSDNで見たらイベントパイプラインではPreRenderの方が後。~
aspxに書いたモノがmasterをオーバーライドできるってことは~
 aspxのLoad→masterのLoad→ 
なんじゃないかと。しかしこの先は…(´・ω・)~
コンテナの記述順でいえばmaster→aspxみたいなのでPreRenderはmasterの方が先っぽいような…(アヤシイ)~
~
~(続く)
~
~


EOF