SGMLReaderがことごとくタイムアウトする件
例えば,
neue cc - C#でスクレイピング:HTMLパース(Linq to Html)のためのSGMLReader利用法からお借りしたこんなコード.
static void Main(string[] args) { XDocument xml; using (var sgml = new SgmlReader() { Href = "http://www.bing.com/search?cc=jp&q=linq" }) { xml = XDocument.Load(sgml); } XNamespace ns = "http://www.w3.org/1999/xhtml"; foreach (var item in xml.Descendants(ns + "h3")) { Console.WriteLine(item.Value); } }
やってることはWebページを取得してそれをXDocumentに突っ込んでるだけなんですが,xml = XDocument.Load(sgml);
のところで必ずタイムアウトでWebExceptionが投げられる.
神が助けて下さいました
泣きついたとも言います.
@HIDARI0415 @shinsukeoda 確かに例外出ますね。調べてみましたが、いつのバージョンからかわからないですがご丁寧にdtd読みに行くようになってますね。IgnoreDtd = trueというのを足せば読みに行かなくなるので動きました!
— neuecc (@neuecc) 2014, 3月 26
つまりデフォルトでは必ずDTD(HTMLタグの前に記述される<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
とかいうやつ)が宣言されてる必要があるということ.
指定が無いデータをSGMLReaderに渡すと今回のように例外が投げられます.
んで,これを無視するように IgnoreDtd = true
って設定することでDTD宣言の無いHTMLでも扱えるようになる,と.
以下,修正した部分のサンプル.
using (var sgml = new SgmlReader() { Href = "http://www.bing.com/search?cc=jp&q=linq" }) { sgml.IgnoreDtd = true; // これが無いと例外で死ぬ xml = XDocument.Load(sgml); }
出力は
LinQ | 九州発のアイドルグループ
リンク - Wikipedia
www.loveinq.com
LINQ: .NET 統合言語クエリ
LinQオフィシャルブログ - Ameba (アメーバ)|無料ブログ ...
LINQ (C# によるプログラミング入門)
LinQ|Warner Music Japan
LinQ・LinK|テレ朝動画 - tv asahi|テレビ朝日
LinQ|HMV ONLINE
LinQ|ニュース|Warner Music Japan - ワーナーミュージック ...
となりました.
おわりに
@HIDARI0415 @shinsukeoda PCL版はDTDまわりバサッとカットされてますね。
— neuecc (@neuecc) 2014, 3月 26
PCL版のSGMLReaderではDTD周りの処理がカットされているということなので,こちらを使えばこの問題は起こらn(ry
@neue先生,@shinsukeoda先生ありがとうございました!
MVVMパターンを少しでも身に付けたかったからTodoアプリを作ることにした
MVVMって言うと「この後めちゃくちゃマサカリ飛んだ」になりそうですが,肝心のソースコードはGithubにて公開しています.
読むだけではわかったつもり、できるつもりになってしまう
さて.
最近わかったつもり,できるつもりになってることが多いです(僕の今までの人生そうじゃなかったことが無いという説はわりと濃厚ですが).
MVVMパターンがそのうちのひとつ.なので,いつか実戦で使えるよう練習することにしました.
そのための小さな題材として以下を使わせてもらいました.
ただ,いきなり元ネタを丸ごと実装するのは僕にとってまだ大きすぎるように感じたので,さらに機能を絞りました.
目的
- MVVMパターンの理解
- 実装の練習
Todoアプリ仕様
- テキストボックスからEnterでTodo項目を追加
- 登録されているTodo項目はチェックボックスでDoneを管理する
- DeleteボタンでDoneになっている項目を削除する
今回は最低限動くものを作ることを目指して,仕様をこれだけにしました.
参考
開発を進めるにあたって主に以下の記事やプロダクトを参考にさせてもらいました.
サンプルレベルからもう一段階上がるためにKanColleViewerはとても参考になりました(同じ書き方で実装している部分が結構…).
今後の予定
元ネタにある仕様の実装を進め,MVVMパターンでの実装の練習にしていけたらなーとかぼんやり考えてます.
たとえば
- フッターに総Todoと残Todoが表示される
- 全選択/解除のチェックボックスの配置
- ダブルクリックによるTodo編集とEnterにによる編集確定
とか.あとUIをなんかこうアバンギャルドな感じにしたい(てきとう).
おわりに
ということでこんなことやってる,やっていきたいっていう意思表明的なエントリでした.
WPF,XAML,MVVMすべてまだまだ初心者なので,「それぜんぜんダメ!こうしたほうがいいよ!!」みたいなのがあれば教えていただけると幸いです.
SYSTEMATIC LOVEなソースコードの写経 #DIVAAC
プレイに集中できなかったので
先日「初音ミク Project DIVA Arcade Future Tone」に追加された「システマティック・ラヴ」(上が本家で下がArcadeのPV).
このPVの後ろに流れてるソースコードがプレイ中にちらちら見えてゲームに集中できなかったから写経してしまいました…これから反省します.
systematic_love.cpp
#include <iostream> #include <math.h> const int HEART_SIZE = 20; const int HALF_SIZE = HEART_SIZE / 2; bool is_in_love(int x, int y); int main(void) { std::string message = " SYSTEMATIC LOVE "; int message_indent = (HALF_SIZE - (message.length() / 4)) - 1; for (int y = 0; y < HEART_SIZE; ++y) { for (int x = 0; x < HEART_SIZE; ++x) { std::cout << ((is_in_love(x, y)) ? "vv" : " "); if (y == HALF_SIZE - 1) { if (x == message_indent) { std::cout << message.c_str(); x += (message.length() / 2); } } } std::cout << '\n'; } return 0; } bool is_in_love(int x, int y) { const float width = 2.2f; const float height = 3.0f; const float HEART_COEFFICIENT = 0.7f; float check_x = ((static_cast<float>(x) / static_cast<float>(HEART_SIZE)) - 0.5f) * width; float check_y = ((static_cast<float>(HEART_SIZE - y) / static_cast<float>(HEART_SIZE)) - 0.4f) * height; float top_y = 0.0f; float bottom_y = 0.0f; if (check_x >= 0) { top_y = sqrt(1 - (check_x * check_x)) + (HEART_COEFFICIENT * sqrt(check_x)); bottom_y = -sqrt(1 - (check_x * check_x)) + (HEART_COEFFICIENT * sqrt(check_x)); } else { top_y = sqrt(1 - (check_x * check_x)) + (HEART_COEFFICIENT * sqrt(-check_x)); bottom_y = -sqrt(1 - (check_x * check_x)) + (HEART_COEFFICIENT * sqrt(-check_x)); } if ((bottom_y <= check_y) && (check_y <= top_y)) { return true; } else { return false; } }
実行すると
つまり,
非常にわかりやすいですね.
おわりに
結婚の高速化と、使うプログラミング言語との相関性について勝手に考えてみた【連載:村上福之】 - エンジニアtype
「コンパよりもコンパイルです。デトックスよりもデバックなのです。」 "Less 'compa' (group blind dates), more 'compile'. Not so much 'detox' as 'debug'". This article's gold.
— Daniel P. Wright (@danielpwright) 2014, 1月 30
プログラム勉強したい人はHello World.の次に書いてみたらいいのでは無いでしょうか(適当
OnStartupをオーバーライドしたらApplication.Resourcesに設定したStyleやらDataTemplateが適用されなかった話
きっかけ
MVVM入門 その1「シンプル四則演算アプリケーションの作成」 in C#, XAML for Visual Studio 2010
のサンプルで,Startupイベントのイベントハンドラ(Application_Startup)でやろうとしてる処理を,overrideしたOnStartイベントハンドラだけで行おうとしたけど,なぜかApp.xaml内のDataTemplateがうまく適用されなかったので,回避方法を模索してみました.
シンプルに再現してみる
まずはVisual Studioで適当にWPFアプリケーションを作成して,MainWindow.xamlにTextBlockのみを置いて実行してみます.
<Grid> <TextBlock Text="HogeHoge"/> </Grid>
こんな感じですね.
このように表示されます.
では次にこれに適当なStyleを定義しましょう.App.xamlのApplication.Resourcesに追加しましょう.
<Application.Resources> <Style TargetType="TextBlock"> <Setter Property="Background" Value="PaleVioletRed"/> </Style> </Application.Resources>
実行するとげろげろな色になるのが確認できます.
ここから,StartupUriを使わず自前でMainWindowを表示するように変更します.
App.xamlのApplication要素からStartupUri属性を削除.
<Application x:Class="WpfApplication2.Views.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" /> <Application.Resources>
AppクラスでOnStartupイベントハンドラをオーバーライドして,MainWindowをShowします.
/// <summary> /// App.xaml の相互作用ロジック /// </summary> public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var window = new MainWindow(); window.Show(); } }
本来ならこれは先ほどと同じげろげろな色で表示されるはずですが
Styleさん,息してません.
適用させるには
手っ取り早くStyleを適用させるにはStartupイベントにイベントハンドラを設定します.Visual Studioがイベントハンドラを生成してくれて楽ですし.
<Application x:Class="WpfApplication2.Views.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Startup="Application_Startup">
コードビハインド(App.xaml.cs)にこんなのが追加されています.
private void Application_Startup(object sender, StartupEventArgs e) { }
中身の無いApplication_Startupメソッドですね.これで実行すると
適用されていますね.
もう一つの方法としては,外部のResourceDictionaryに移してしまい,それをSource属性を使って読み込む方法です.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style TargetType="TextBlock"> <Setter Property="Background" Value="PaleVioletRed"/> </Style> </ResourceDictionary>
という内容のDictionary1.xamlを
<Application.Resources> <ResourceDictionary Source="Views/Dictionary1.xaml"/> </Application.Resources>
とすることでもうまく適用されます.
結局
回避する方法としては,
- 大人しくStartupUriのお世話になる
- 何も考えずStartupイベントのイベントハンドラを設定する
- ResouceDictionaryを外部ファイルに追い出す
とかでしょうか.ちなみに3番目が好み.
とりあえず僕にわかったのはここまでです.結局原因はわからなかったので誰か教えてください.私,気になります!
おまけ
先日の Room metro #22 で @yone64 さんに教えて貰ったのですが,App.xamlにStartupを書かず,コードビハインドにApplication_Startupメソッドだけが定義されてる状態でもStyleが適用されるという謎の挙動をします.
なにか闇を見た気がします.
StyleCopインストール手順メモ
今風のStyleCopインストール
今風かと言われると今更風なのかもしれませんがね(その2).
この記事は NUnitのインストール手順メモ - HIDARI日記(右) の続きようなものです.
nugetしませんか(再)
- [ツール] - [ライブラリ パッケージ マネージャー] - [パッケージ マネージャー コンソール] を開きます
- [既定のプロジェクト] をテスト(があるプロジェクト)に設定します
Install-Package StyleCop.MSBuild
を入力して [Enter]- パッケージのインストールが完了するまでほんの少し待機
- [ビルド] - [ソリューションのクリーン] を実行します
- 改めてプロジェクトをビルドします
- [エラー一覧] にStyleCopで検出されたルール違反が表示されます
検証のルール変えたいですね
デフォルトの検証ルールは厳しすぎるのでStyleCopに付属のGUI設定ツールで変更します.
デフォルト設定ファイルは packages\StyleCop.MSBuild.4.7.46.0\tools\Settings.StyleCop
なので、今回はこれを直接編集することにします*1.
コマンドプロンプトからソリューションのディレクトリの下にある packages\StyleCop.MSBuild.4.7.46.0\tools
に移動します.
StyleCopSettingsEditor.exe Settings.StyleCop
厳しすぎたり必要なさそうなルールのチェックを外して [OK] を押します.
詳しいルールの説明(ちょっと古いかも)は 漫坊亭@ウィキ - トップページ/CSHARP/StyleCop - @ウィキモバイル 、StyleCop Rules (英語)あたりが参考になると思います.
設定ファイルは対象プロジェクトの直下から親ディレクトリを辿り、デフォルトへ向かって検索され、最初に見つかった Settings.StyleCop が使用されます.
複数のソリューションで使用する場合にはリポジトリ内のルートとかに置いておくのが楽といえば楽かもしれないですね。 そういった設定ファイルを編集するには、先ほど使用したGUI設定ツールを起動するコマンドを使い
StyleCopSettingsEditor.exe PATH\TO\Settings.StyleCop
と指定します.
またデフォルト以外の Settings.StyleCop を使用している場合、他の場所にある Settings.StyleCop をマージして使用することもできます.
- GUI設定ツールを開きます
- [Settings Files]タブを選択します
- [Merge with the following setting file:]から任意の Settings.StyleCop を選択します
- [OK]を押します
それでも私はVisual Studioに統合したい
- StyleCop - Home から最新のmsiをダウンロード
- インストールします(数分かかると思います)
- Visual Studioの[ソリューション エクスプローラー]でプロジェクトでコンテキストメニューを表示し [Run StyleCop] を実行します
- [エラー一覧]に警告が表示されます
画像内のコンテキストメニューにしれっと表示されている通り,ここから [StyleCop Settings] を選択することで設定ツールを起動することもできるようになります.
なおこの方法でインストールする場合、StyleCopの実行は手動で行う必要があります.
nugetでインストールした場合のようにビルドにフックして実行するにはcsprojファイルを直接編集するなどの小細工が必要になります.
ちょいと面倒ですがこうすることでGUI設定ツールをVisual Studio上のコンテキストメニューから起動できるようになります.
まあ両方インストールすればいい・・・のか?
そういえば
nugetからインストールしたStyleCopの検証を手軽にオン/オフにする(もしくは検出された違反を表示/非表示にする)方法ご存知の方,いらっしゃいましたら教えていただきたいです.
なんでせっかく問題があることを教えてくれてるのにそんな事するんだって?
僕もそう思います.あとからまとめて修正したいんですかね.
NUnitのインストール手順メモ
今風のNUnitインストール
職場で何度も手順を書かされることにいい加減嫌気がさしたので,今度から投げつけられるようにまとめておくことにします.
今風かと言われると今更風なのかもしれませんがね.
少なくとも弊社ではインストーラを落としてきてインストールするよりもnugetからインストールするほうが,在る筈のないハードルは低いようです.
nugetしましょう
Visual Studioを開き,メニューから [ツール] - [ライブラリ パッケージ マネージャー] - [パッケージ マネージャー コンソール]を開きます.
パッケージ マネージャー コンソールの上部右側にある [既定のプロジェクト] をテストがある(あるいはテストを書く予定の)プロジェクトに設定します.
パッケージ マネージャー コンソールに
Install-Package NUnit
と入力して [Enter].
NUnitがインストールされ,プロジェクトの参照設定まで行われます.
次に先ほどNUnitをインストールしたプロジェクトの中のテストコードを開いて,他のusingディレクティブの下あたりに
using NUnit.framework;
と書きます.
加えて,いい感じにテストを書いておきます(テストの書き方は NUnitの全貌 ~ 基本から、最新バージョンの新機能まで (1/8):CodeZine あたりを参考にどうぞ).
Test Adapterしましょう
Visual Studioのメニューで [ツール] - [拡張機能と更新プログラム] を開きます*1.
左のメニューから [オンライン] - [Visual Studio ギャラリー] を選択します.
右上の [Visual Studio ギャラリーの検索(Ctrl+E] に「NUnit Test Adapter」と入力します.
「NUnit Test Adapter」の [ダウンロード] を押します.
「ダウンロードとインストール」画面が表示されるので進めます.
インストールが終わったらVisual Studioの再起動を求められるので大人しく再起動します.
テストエクスプローラーが表示されていなければ [テスト] - [ウィンドウ] - [テストエクスプローラー] から表示します.
Testしましょう
もしまだテストを書いてなければ,とりあえず適当に書いてビルドします.
[テストエクスプローラー] にテストが表示されます.
[テストエクスプローラー] の上部にある [すべて実行] 等の実行ボタンを押すとテストが走ります.
それでも私はGUIが好き
Visual Studioのテストエクスプローラーが嫌いっていう方もいらっしゃるようなので.
NUnitのGUIには.NET Framework3.5が必要なので観念して事前にインストールしておいてください(マイクロソフト公式ダウンロード センターから Microsoft .NET Framework 3.5 をダウンロード).
Visual Studioの [パッケージ マネージャー コンソール] を再度開きます.
Install-Package NUnit.Runners
を入力して [Enter].
インストールが終わったらソリューションのディレクトリを開き packages\NUnit.Runners.2.6.3\tools\nunit.exe
(32bitならnunit-x86.exe)を実行します.
ところで,.NET Framework3.5がインストールされていないと,このタイミングで…
こんなことになります.まあこの状態からインストールすればいいんですが.
さて,気を取り直してGUIの [Tools] - [Settings] で設定画面を開きます.
左のツリーから [IDE Support] - [Visual Studio] を選択します.
[Enable Visual Studio Support] にチェックを入れます(これでプロジェクトファイルが読み込めるようになります).
[OK] を押して設定画面を閉じます.
[File] - [Open Project...] からテストがあるプロジェクトファイル(.csprojファイル)を選択します.
テストがロードされるので [Run] を押せばテストが実行されます.
Settingsにはもっと便利な項目もあるので時間のあるときにでも見てみると幸せになれるかもしれません.
それでも私はインストーラが好き
なんでもかんでもVisual Studioにくっつくのがイヤだという方もいらっしゃるようなので.
NUnitのインストーラを使う場合にも.NET Framework3.5が必要なので観念して事前にインストールしておいてください.
NUnit - Download から最新安定板のmsiをダウンロードし実行します.
インストールは基本的には一本道ですが,唯一途中で「Setup Type」を聞かれます.
[Typical] で問題ないはずです.
まあ
便利ですよね,nuget.
*1:拡張機能はVisual StudioのExpressでは使えないのでNUnitのGUI使うことになりますのでご注意を.
Developers Summit 2013 Kansai Action! (デブサミ関西2013)に参加してきました #kansumi
デブサミとデブサミ関西の存在自体は知っていましたが,去年(デブサミ2012)は参加できなかったので,来年こそは!と考えていたのですが…
まさか自分がスピーカー
として参加することになるとは1年前には思いもしませんでした.
という訳でデブサミ2013関西のランチセッションで発表させて頂きました. スライドは以下.
内容としては
これまで開発の現場で僕自身がどういう意識で何を行ってきたのかを紹介するという非常に簡単なものでしたが,かなり多くの方に聞いて貰うことができ,さらに何人かの方には興味を持ってもらえたようで発表後にもお話させていただくなど,とてもよい経験になりました.
スタッフの皆様,僕の発表をお聞きいただいた皆様,本当にありがとうございました.