- 追加された行はこの色です。
- 削除された行はこの色です。
- 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