start

C#でローカルのDTDファイルを使うXMLリゾルバを作る

以前、C#でXmlDocumentを作る時にリゾルバでタイムアウトすると書いたが、ようやくローカルのDTDファイルを使ったXMLリゾルバが作れたので、コードをまるっと公開。尚、.NET Framework 4では殆ど同じことを行うXmlPreloadedResolverクラスが追加されているので、使えるならそっちを使うのが良い。悲しいかな、うちは.NET 3.5なのさ……

using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;
 
namespace ProductionKusoGA
{
    class LocalXmlResolver : XmlResolver
    {
        public LocalXmlResolver()
        {
        }
 
        public override System.Net.ICredentials Credentials
        {
            set {  }
        }
 
        public override Uri ResolveUri(Uri baseUri, string relativeUri)
        {
            Uri uri = DocTypeManager.Instance.GetDTDURI(relativeUri);
            return uri != null ? uri : base.ResolveUri(baseUri, relativeUri);
        }
 
        public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
        {
            object entity = DocTypeManager.Instance.GetDTDStream(absoluteUri.AbsoluteUri);
            if (entity == null)
            {
                XmlUrlResolver resolver = new XmlUrlResolver();
                entity = resolver.GetEntity(absoluteUri, role, ofObjectToReturn);
            }
            return entity;
        }
 
        class DocTypeManager
        {
            public static readonly DocTypeManager Instance = new DocTypeManager();
 
            public Uri GetDTDURI(string inFPI)
            {
                Uri dtdURI = null;
                URIForFPI.TryGetValue(inFPI, out dtdURI);
                return dtdURI;
            }
 
            public FileStream GetDTDStream(string inURI)
            {
                FileStream stream = null;
                if (DTDStreamForURI.TryGetValue(inURI, out stream) == false)
                {
                    string dtdFile = null;
                    if (DTDFileForURI.TryGetValue(inURI, out dtdFile))
                    {
                        string RESOURCE_DIR = "...";
                        stream = new FileStream(Path.Combine(RESOURCE_DIR, dtdFile), FileMode.Open);
                        DTDStreamForURI.Add(inURI, stream);
                    }
                }
                return stream;
            }
 
            DocTypeManager()
            {
                URIForFPI = new Dictionary<string,Uri>();
                DTDFileForURI = new Dictionary<string,string>();
                DTDStreamForURI = new Dictionary<string, FileStream>();
 
                AddDTD("-//W3C//DTD XHTML 1.0 Strict//EN",      @"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",       @"path/to/xhtml1-strict.dtd");
                AddDTD("-//W3C//DTD XHTML 1.0 Trasitional//EN", @"http://www.w3.org/TR/xhtml1/DTD/xhtml1-trasitional.dtd",  @"path/to/xhtml1-trasitional.dtd");
                AddDTD("-//W3C//DTD XHTML 1.0 Frameset//EN",    @"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd",     @"path/to/xhtml1-frameset.dtd");
                AddDTD("xhtml-lat1.ent", @"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent", @"path/to/xhtml-lat1.ent");
                AddDTD("xhtml-symbol.ent", @"http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent", @"path/to/xhtml-symbol.ent");
                AddDTD("xhtml-special.ent", @"http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent", @"path/to/xhtml-special.ent");
            }
 
            ~DocTypeManager()
            {
                foreach (var pair in DTDStreamForURI)
                {
                    if (pair.Value != null)
                    {
                        pair.Value.Dispose();
                    }
                } 
            }
 
            void AddDTD(string inFPI, string inURI, string inFilepath)
            {
                URIForFPI.Add(inFPI, new Uri(inURI));
                DTDFileForURI.Add(inURI, inFilepath);
            }
 
            Dictionary<string, Uri> URIForFPI { get; set; }
            Dictionary<string, string> DTDFileForURI { get; set; }
            Dictionary<string, FileStream> DTDStreamForURI{ get; set; }
        }
    }
}

DTDファイルのパスを適宜変更し、xmlDocument.Resolver = new LocalXmlResolver();ってな感じで設定してやればおk。DTDを増やしたいときはAddDTDを増やす。DTDが内部で参照しているファイル(上記コードで言えばxhtml-lat1.entとか)も漏れなく追加する必要がある。

一応、コードのライセンスはパブリックドメインってことで。煮るなり焼くなりお好きにどうぞ。

Blueprintで構造体のメンバ変数の値を設定する方法

UE4のBlueprintで、構造体のメンバ変数に値を代入する方法が分かりにくいのでメモ。構造体のインスタンスを新しく作るのではなく、既存インスタンスのメンバを変更するって事ね。

メンバの数がさほどないなら、新たにインスタンスを作って古いインスタンスと全部ピンで繋ぐって方法でも行けなくはない。しかしながら、不要な一時インスタンスは作らないというのがプログラマ的矜持なのである。何より美しくないしねぇ…。覚えておいて損はないよ!

ebayで買い物したらi-Parcelで送られてきたでござるの巻

1月の事になるが、ebayでアメリカの業者からPCのキーボードを購入したらi-Parcelで送られてきた。この配送業者、検索すれば分かる通り評判があまりよろしくない。送料で20ドル払ってるのにこんなのって酷いよ(´;ω;`)。

荷物は無事届いたものの噂通り時間がかかった。参考までに到着までの記録を載せておこう。

日時 状況 場所 備考
2016/1/24注文
2016/1/25Pre-Shipment Info Sent to USPS 配送情報登録
2016/1/26 10:37Accepted at USPS Origin FacilityLAKEWOOD, NJ 08701引受
2016/1/26 11:52Arrived at USPS Origin FacilityKEARNY, NJ 07032発送元配送局到着
2016/1/27 19:30Arrived at USPS Destination FacilityCINCINNATI, OH 45235目的地配送局到着
2016/1/28 07:20DeliveredERLANGER, KY 41025配達済み
⇩i-parcelに引き継ぎ⇩
2016/1/29 20:34Package details received electronically from SellerEdison配送情報登録
2016/2/01 17:51Received at i-ParcelIndianapolis荷物到着
2016/2/01 21:44Exported i-Parcel and in transit to country of destinationIndianapolis日本に向けて出荷
2016/2/05 14:17Package arrived in the destination country and is awaiting release from the Customs clearing agency日本日本到着。通関待ち。
2016/2/05 17:34Completed customs clearance process日本通関手続き完了
2016/2/06 12:49Out for delivery日本持ち出し中
2016/2/07 15:27Delivered日本配達済み

と、まぁこんな感じでまるっと2週間かかった。ネットの情報通り、国内配送は佐川だった。

時間かかるのはいいんだけっともさ、追跡情報の更新が遅いのは頂けないっすねぇ…。中国邮政より精度悪いんですぜ?荷物受領後もしばらくは「日本に向けて出荷」のままだったし……。何のためのトラッキングなんだよっていう。

Firefoxのリセットは内蔵の「Firefoxをリフレッシュ」が便利

動作が重くなったFirefoxを復活させる手立てとして、Firefoxのキャッシュや履歴の削除という手段が良く用いられる。ちょっと探せばその為のアドオンや解説ページはゴマンと出てくるが、いつ頃からかFirefox自体にリフレッシュ機能が実装されたようだ。

メニューの``[ヘルプ]>[トラブルシューティング情報]``を選択、もしくはアドレスバーに``about:support``と入れて開くと「トラブルシューティング情報」ページが開き、右上にある「Firefoxをリフレッシュ」ボタンを押すと掃除が行われる。

この機能の何が便利って、ブックマークや保存したパスワード、Cookie、開いているタブ情報などは残したまま、拡張機能やツールバーなどのデータだけを消してくれる。で、掃除前のプロファイルはOld Firefox Dataとしてデスクトップに保存されるので、もしリフレッシュ後の状態に支障があればリフレッシュ前に戻すことも可能。素晴らしい。

実際に、プチフリやらAjaxのセッション切れ?が頻発しFirefoxを再起動するまでサービスが使えなくなる状態のFirefoxをリフレッシュしてみたところ、見事に問題が解消された。素晴らしすぎる。

前述の通り、拡張機能とその設定が全てなくなるので、拡張しまくってる人には辛いかもしれないが、リフレッシュを気にアドオンの見直しを行うってのも一興ではなかろうか。Firefoxが重くなる原因は大抵アドオンにあるわけだし。ちなみに、自分はもうツリー型タブとμBlock Originしか入れてない。

良きFirefoxライフを!

Firefoxの消えてしまった「以前のセッションを復元」を復元

転ばぬ先の杖というわけで、大変素晴らしいアドオンTab Session Managerを入れておきましょう。

Firefoxの再起動時、何かの弾みでタブのセッション情報が消失し「以前のセッションを復元」が使えなくなることがある。ブックマーク前の有益なサイトを開いてたりすると、さぁ大変だ。

どうにか復元出来ないものかと悪あがきしてたら、以下の方法でセッションを復元出来るようだ。

  1. 現在のプロファイルフォルダを開く
    • メニューの [ヘルプ]>[トラブルシューティング情報] の「プロファイルフォルダ」から開くのが簡単&確実。
      • 以下、プロファイルフォルダをmyprofile.defaultとする
  2. Firefoxを完全に終了する(メニューから終了させるのが確実)。
  3. myprofile.default/sessionstore-backups フォルダの中から“それっぽい”セッション情報ファイルを探す。ファイルはJSONなので普通にテキストファイルで開ける。
    • ここで見つからなければ試合終了なので素直に諦めて下さい。
  4. 見つけたファイルをmyprofile.defaultフォルダにコピーし、sessionstore.jsにリネーム。
    • このファイルが「以前のセッションを復元」で使われている模様。すでに存在してたら上書きでおk。
  5. Firefoxを起動すると「以前のセッションを復元」が使えるようになっているハズ。

いやしかし、このセッション情報を壊したくないからプロファイル切り替えたってのに、いつものプロファイルに戻ったら見事にクリアして下さりやがったのは、どういう了見なのMozillaさん(´・ω・`)?

  • start.txt
  • 最終更新: 2022-07-27 15:26
  • by Decomo