ホームページについての日記

このページについて

このページは、JavaScript+PHPで作っている「ホームページについての日記」をHTML版に直したページです。

GoogleYahooなどの検索エンジンに拾われてもかまわない内容だけを書いてます。検索エンジンに拾われたく内容は書いてません。

最新のページはあるていど項目別にわかれてます。

2011年1月7日
WebKitやIEはJSON2.JSで変換すると、エラーを出して処理が出来ない場合がある。POSTするのだから「文字列」の情報だけあればよいわけだ。よけいなオブジェクトは変換する必要がない。
JavaScriptでオブジェクトからデータを取得するためには、for(~ in ~)文でKEYと値を取得して、「文字列」だけのオブジェクトを作ればJSON2で変換できるのである。
function JSON_POST (Object) {
  var POST_Object = new Object;
  for(key in Object){
    try {
      if (!Object[key].length) {
          POST_Object[key] = "";
      } else {
          POST_Object[key] = Object[key];
      }
    }
    catch (e) {
         POST_Object[key] = "";
    }
  }
  return POST_Object;
}
要するに、「lengthを調べて取得できない配列は空のデータにする。」だけです。
for(~ in ~)は、指定したオブジェクト全てを取得します。自分が使いたいオブジェクトを把握していないと、おかしなことになるので注意が必要です。
これで、JSON.stringify()してあげれば、ブラウザに関係なくPHPにJSONのデータを送れるわけだ。POSTをひとつにまとめられるのは、かなりうれしい。
もうちょっとがんばれば、JSONのデータフォーマットも作れそうですが、JSON.parse()を使いたいので、この辺りはがんばらない。素直にJSONの関数を利用する。
2011年1月14日
検索ワードで目についたことについてちょっとコメントします。

css column offsetleft webkit(Chrome/7.0.517.44)

現状のWebKitはcolumnを使い分割した場合、分割された右の領域に表示されたDOMオブジェクトのoffsetがちゃんと取得できないようです。

2010年のの釣り日記で、a要素のoffsetを取得して、その位置に画像を表示しているのですが、webKitは上手く表示しません。

表示するのを気長に待ちましょう。

css フラグメント "戻ってしまう"(Firefox/3.6.13)

「戻ってしまう」が曲者で、「指定したのに反映しない」を意味している思います。(CSS フラグメントの構文はAppendix G. Grammar of CSS 2.1,Selectors Level 3に記載されてます。

セレクタの重みでスタイルの反映順が変わってしまうので、「勘違い」で反映していないと思っているのかもしれません。

Fxならば、DOM Inspector で確認できるので、どのstyleが適応されているのか覗いてみましょう。

xslt transformToFragment webkit null(Chrome/8.0.552.215)

webkitでも、transformToFragmentは動きます。createDocumentのloadができないだけです。

WebKit対応版-XSLTProcessorで紹介してます。

WebKitのXSLTProcessor()は、XSLTがinclude出来ないようです。その辺を考慮する必要があると思います。

chrome js xml load(Chrome/8.0.552.215)

webkitは、CreateDocumentのloadができません。したがって、XMLHttpRequest()を使って、GETメゾッドでXMLファイルにアクセスして、responseXMLでXML文書を取得します。

WebKit対応版-XSLTProcessorで使ってます。

canvas svg 使い分け(MSIE 8.0)

IEを使っている人はまだ考えなくて良いです。作ってみたところで使えないですから。

動きがある図を作りたいならcanvas。マウスの動きによって説明の表示などはSVG JavaScriptとしています。

canvas要素を使ってみた。で話題にはしてます。

Musimusi ファイル(MSIE 8.0)

私のページがトップにきたんですね。知りませんでした。

html5 canvas ポインタ 位置 取得(Chrome/8.0.552.224)

ポインタの位置 - Canvasのoffset位置 - スクロール量で計算します。

canvas要素に「お絵かき」機能。で書いてます。

2011年1月17日
検索ワードに、「dublin core サンプル html xhtml」ってあった。過去にやったことがあるのだが、あまり有意義ではないと思って却下したことがある。
却下した理由として、 当時のdublin coreは、「基本となる15の要素タイプ」 「拡張プロパティ」で、「基本の要素では足りない、拡張を使うには名前空間を、もう一つ指定しなくてはならず面倒くさい。またその当時は、DOMを扱うスクリプトを使いはじめたばかりで、dublin coreの語彙を使うことによって、JavaScriptを大幅に変更することになり、その手間を考えると「しないほうがよい」という結論になった。
今日現在でも、「dublin coreの語彙」を現状のXHTMLに追加するとDOM構造が変わってしまい、JavaScriptが動かなくなるので、スクリプトが動いているページには「dublin coreの語彙」の追加はやりにくいのですが、スクリプトが動いてないページでやる文には、特に問題がないので、やってみる。
"http://purl.org/dc/terms/"で表される名前空間は「基本となる15の要素タイプ」 「拡張プロパティ」が定義されているので、名前空間を一つだけ使えばよい。
html要素に、xmlns:dcterms="http://purl.org/dc/terms/"を追加する。後は、必要な要素を追加していく。
dcterms:title(正式タイトル)dcterms:tableOfContents(リソースの目次)dcterms:abstract(リソースの要約)を定義してみたが、いまいちです。
文章の中の「モノ」の紹介などに、「dublin core」のマークアップはキチンとはまるとおもいます。そちらのほうで使ったほうがよろしいと思います。
しかし、書いたところで使われることは現状ではあまりないと思います。
2011年1月24日
「クロスドキュメントメッセージ」は指定のiframe要素で指定したページの「messageイベント」に、テキストデータを送る仕様なので、JSONが使えるはずである。
送信側は、JavaScriptの連想配列をJSON2のモジュールを使用してJSONフォーマットに変換し、指定のiframe要素に、iframeObject.postMessage(JSON)する。受け取った側は、JSON2のモジュールを使用してJavaScriptの連想配列に戻せばよいわけだ。
JSONはテキストで連想配列は受け渡す仕様なので、「クロスドキュメントメッセージ」でも当然つかえるはずである。
実験は、上手くいきました。IE7-が使えなくなりましたが、そんなブラウザは切り捨てです。
2011年2月2日
検索ワードで目についたことについてちょっとコメントします。

php simplexml link rel http://www.w3.org/2005/Atom registerXPathNamespace(Firefox/3.6.13)

「PHPのsimplexmlでXPathを使いたい。」みたいなことでしょう。「XPathがわかる」ことが前提となります。

registerXPathNamespaceは、simplexmlで読み込んだXML文書に名前空間を指定するコードです。XML文書で言うところの「xmlns」にあたります。 例えば、ATOMの名前空間を指定する場合、XML文書ならば、xmlns:atom="http://www.w3.org/2005/Atom"と書きます。

これを、simplexmlで指定する場合に、registerXPathNamespaceを使います。

$xml = simplexml_load_file ($fileURL);
$xml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');

こうすると、XPathが使えるようになります。entryのtitleを取得したいなら、$entryTitle = $xml->xpath('//atom:entry/atom:title');と書けば、entryのtitleを取得できます。

ただし、XPathで取得した要素は、ReadOnlyになります。addChildなどはできないので注意が必要です。

webkit translation 楕円 css3(Chrome/8.0.552.231)

CSS3で楕円を使いたいなら、border-radiusを使うと思うのですが……。translationは要素を回転させることの出来る指定です。

border-radiusで楕円を作るのは、ちょっと工夫が必要だと思います。

Firefox javascript send null 停止(MSIE 8.0)

JavaScriptでsend nullする場合は、XMLHttpRequestで送信した使った場合だと思います。その場合onreadystatechangeプロパティーを使って、状態を確認したらよいとおもいます。

readyStateが「4」でstatusが「200」の場合通信が成功しています。readyStateが「4」でstatusが「200」以外の通信の場合statusを表示をさせます。

あとは、statusの情報で判断してください。停止しているとは思えません。

Microsoft.XMLDOM ie8(MSIE 8.0)

Microsoft.~は、IE4~IE6にかけてXMLを扱うためのActiveXObjectです。IE6以降は、MSXML.~が使えますのでそちらを使うようにしましょう。

Microsoft.~でサンプルが書いてあったりするページは、古い情報を元に作られているので困ったことが起きるかもしれません。

firefox 3.6 onmousemove 引数がとれない(MSIE 8.0)

obj.addEventListener("click",function(){XMLTest("test.xml")},false);と無名関数を使えば引数は渡せます。

addEventListenerは、イベントオブジェクトは取得できるので、targetでDOMオブジェクトを取得して属性などに引数を忍ばせて使うことも出来ます。

まぁ、やりかたしだいです。個人的には無名関数を使いたくないです。

重ねた下の画像にクリックイベントを適応 js(MSIE 8.0)

重ねた下の画像にaddEventListenerでクリックイベントを適応。重ねた上の画像にDispatchEVENTで重ねた下の画像のクリックイベントを動かすイベントを適応。

それで、下のイベントはうごきます。

csv をhtmlで表示する スクリプト firefox(Firefox/3.6.6)

  1. XMLHttprequestオブジェクトで、CSVファイルをresponseTextでGETします。
  2. 改行コードでsplitして行単位にします。
  3. CSVの取り決めに応じて区切り文字でsplitして、項目ごとにします。
  4. その結果をHTMLの要素をつけて表示します。

この手順を踏めば、Fxに限らず使えます。

2011年2月10日
Android 携帯でXSLTについて検索している人がいた。Android 携帯のWebKitはXSLTProcessorが使えないので、JavaScriptでXSLTを使って変換が出来ません。
XMLにXSLTをスタイルシートとして適応させても反応しません。Android 携帯のブラウザでXMLをコンテンツとして使えないので、工夫が必要です。
Android 携帯のSafariに改善を求めます。
2011年2月18日
HTML5には、「Custom Data Attribute」なるものがある。独自属性には先頭に必ず「data-」をつけなさい。この属性の値はDOMからも取得できる。となってます。
さて、この属性をどのように使おうか悩んでいたのですが、最近 Androidで接続する人がいる。画像のリンクをクリックすると、AndroidはXSLTが使えないため、別サーバーでXSLTの処理をして表示しているのですが、Android携帯で見る場合、軽さが無い。PCの場合気にならないのですが、携帯の場合重く感じてしまう。
クリックして、画像だけ表示すればよいように思えるが、それでは芸がない。やはり画像の説明は出したい。しかし、XMLで他文書を読んでいたのでは重くなる。
「Custom Data Attribute」である。簡単なメタデータを属性として記述できる。その情報を画像と一緒にに表示してしまえばよい。HTMLに埋め込んでいるので、他文書を読む必要もなく軽くなるはずです。
<a data-place="七北川河口近くの浅瀬" data-dete="2010-10-24" class="img" href="http://musimusi.g.ribbon.to/img/foaf/20101024haze.xml">20cmに足りないハゼ</a>と書いて、
<h2>20cmに足りないハゼ</h2>
<p>七北川河口近くの浅瀬</p>
<p>2010-10-24</p>
<img src="http://musimusi.g.ribbon.to/img/img/20101024haze.jpg"/>
なソースをJavaScriptで生成する。
余計な通信をしないので、表示も早いです。こんな使い道もありだと思います。
2011年2月22日
GoogleとYahoo!で検索する人の使うブラウザの傾向が面白い。
Google
  1. IE-55%
  2. Fx-19%
  3. Safari-14%
  4. Chrome-11%
  5. Opera-1%
比較的分散している。WebKit系が多いのもわかりやすい
Yahoo!
  1. IE-89%
  2. Safari-5%
  3. Fx-4%
  4. Chrome-1%
ほぼIEである。Yahoo!を使う人のほうが、日本の一般人なのかも知れない。
ちなみに、Web系の検索は、Googleが圧倒的に多い。作る側の人はGoogleを使ってます。しかし、閲覧者全体からみれば、5%未満しかなく、5%の作る人に95%の使う人、見る人が居るように見える。
まぁ、そんなものだろう。
2011年2月24日
WebKit系のXSLTの処理が、xml-stylesheetとXSLTProcessorで挙動が違う。
xml-stylesheetでは、document()が使えるのだが、XSLTProcessor()では使えない。他文書からデータをつけるXSLTの場合、他文書からの情報が抜け落ちることになる。
自分自身以外のXSLTはまったく使えないことになる。includeもdocumentも使えないとなるとかなり使えないです。
HTML5,CSS3に対応するなら、XSLTProcessorぐらいきちんと対応してください。他ブラウザと比較してかなりのマイナスです。
「なんとなく趣味のページ」では、各ブラウザで困ってます。
Firefox
SVGのグラデーションをマウスイベントで変化するようにしているのだが、変化しない。
opacityをJavaScriptで透明-不透明にして画像を少しずつ表示しているのだが、いきなり表示してしまう。
Chrome
columnで位置をずらした場合、位置を把握できずに、元の位置に表示をしてしまう。
SVGのリンクが発生する領域が狭い
XSLTProcessor()が、document(),includeが使えない。includeはXSLTprocessorがとまる。
SVGのグラデーションが微妙になる
opacityをJavaScriptで透明-不透明にして画像を少しずつ表示しているのだが、いきなり表示してしまう。
Safari
columnで位置をずらした場合、位置を把握できずに、要素を見えなくしてしまう。
SVGのリンクが発生する領域が狭い
XSLTProcessor()が、document(),includeが使えない。includeはXSLTprocessorがとまる。
opacityをJavaScriptで透明-不透明にして画像を少しずつ表示しているのだが、いきなり表示してしまう。
Opera
CSSのグラデーションができない。
CSSのcolumnができない。
CSSのBoxができない。
IE
html5に対応していない。
SVGに対応していない。
CSS3に対応してない。
中途半端に対応されると、アクセスしにくかったり、出来なかったりして困ります。
それなら対応しないほうがとても助かります。
だからといって、なにも対応していないIEは評価の対象外です。

なんとなく趣味のCSS3

border-image

-- WebKit --
-webkit-border-image: url(../css/img/pin_s.png)20 / 20px repeat repeat;
-- Gecko --
-moz-border-image: url(../css/img/pin_s.png)20 / 20px repeat repeat;
-- Opera --
-o-border-image: url(../img/pin_s.png)20 20 20 20 / 20px 20px 20px 20px repeat repeat;
-- CSS3 --
border-image: url(../css/img/pin_m.png)30 30 30 30 / 22px 22px 22px 22px repeat repeat;

border-image

-- WebKit --
-webkit-border-image: url(../css/img/scotch-tape.png) 2 8 2 5 / 2px 8px 2px 5px;
-- Gecko --
-moz-border-image: url(../css/img/scotch-tape.png) 2 8 2 5 / 2px 8px 2px 5px;
-- Opera --
-o-border-image: url(../css/img/scotch-tape.png) 2 8 2 5 / 2px 8px 2px 5px;
-- CSS3 --
border-image: url(../css/img/scotch-tape.png) 2 8 2 5 / 2px 8px 2px 5px;

box-shadow

-- WebKit --
-webkit-box-shadow: 10px 10px 10px #99eeFF;
-- Gecko --
-moz-box-shadow: 10px 10px 10px #99eeFF;
-- CSS3 Opera --
box-shadow: 10px 10px 10px gray;

border-radius

-- WebKit --
-webkit-border-radius: 10px;
-- Gecko --
-moz-border-radius: 10px;
-- CSS3 Opera --
border-radius: 10px;

text-shadow

text-shadow: 5px 5px 10px #808080;

linear-gradient

-- WebKit --
background: -webkit-gradient(linear, left top, right bottom, from(rgb(255,222,255)), to(#ffffdd));
-- Gecko --
background: -moz-linear-gradient(top, rgb(255,222,255),  #ffffdd);
-- CSS3 --
background: linear-gradient(top, rgba(255,222,255,0),  #ddffdd);

transform

-- WebKit --
-webkit-transform: rotate(-12deg);
-- Gecko --
-moz-transform: rotate(-12deg);
-- Opera --
-o-transform: rotate(-12deg);
-- CSS3 --
transform: rotate(-12deg);

column

-- WebKit --
-webkit-column-count: 2;
-webkit-column-gap: 3em;
-webkit-column-rule: 1px solid #99cc99;
-- Gecko --
-moz-column-count: 2;
-moz-column-gap: 2em;
-moz-column-rule: 1px solid #99cc99;
-- CSS3 --
column-count: 3;
column-gap: 3em;
column-rule: 1px solid #cc99ff;

display:box

display-BOX
display: -moz-box;
display: -webkit-box;
display: box;
-moz-box-flex:1;
-webkit-box-flex:1;
box-flex:1;
-moz-box-flex-group:1;
-webkit-box-flex-group:1;
box-flex-group:1;
(未対応かも)
2011年4月8日
HTML5にSVGを含めることが可能らしい。実際FirefoxやChromeが出来ると謳ってます。「なんとなく趣味のページ」は独自の見方によって出来るを判断します。
  1. HTML内にSVGを書いて認識されること。
  2. 外部CSSを適応出来ること。
  3. XLINKを使わずにJavaScriptが適応できること。
最低この3つをクリアしないと出来る。とは謳えません。
「HTML内にSVGを書いて認識されること。」FirefoxやChromeともにOKです。
「外部CSSを適応出来ること。」HTMLのLINK要素に書いて反映できればOKなのですが、これもOKです。
「XLINKを使わずにJavaScriptが適応できること。」HTMLの外部script要素で適応できればOKなのですが、とりあえず出来ます。ただし、挙動がおかしいです。HTMLで規定している属性名しか取得できない。
XMLで書いてあるのだから、HTMLでの属性だけを拾うのはおかしい。SVG要素には、xmlnsが定義されているので、SVG要素の子要素はHTMLの縛りから開放されないといけない。
改善を要求します。
アイナメの観察で実験しています。
2011年5月10日
~そこのけ雀~ まとめなページ-JavaScriptで、「Webkit系のJavaScriptでXMLをXSLTで適応させる方法」として紹介されていた。
その中ページに、「jsファイル内でjsファイルをインクルード」の方法が書いてあった。ようするに、script要素をappendChildすれば出来ると紹介されていた。
その方法は、「loadイベントの最初で必要なスクリプトをhead要素に追加する。」という挙動です。loadイベントの場合、HTMLの読み込みが完了した時点で追加されます。その方法なら、script要素をHTMLに書いたほうが、確実に読み込まれます。 同じスクリプトを使うHTML文書が多くて修正が面倒ならば、この方法でも有効だと思いますが、今時ブログなどのプログラムでHTMLを生成する場合、script要素の多さはあまり気にならないと思います。プログラムなら、1回書いてしまえよいだけです。
私の希望は「DOMを使わずにscritpを使いたい」です。「使いたいスクリプトをhead要素に追加する。→ブラウザが対象のスクリプトを評価する。→評価後のスクリプトを使用する。」のではなく、 「使いたいスクリプトをスクリプトに読み込む。→スクリプトが対象のスクリプトをブラウザに評価させる。→評価後のスクリプトを使用する。」要するに、ブラウザ任せにするではなく、スクリプト製作者の意思でやりたいのです。
上記の流れは
  1. XMLHtteRequestでJSファイルを読み込む
  2. JSファイルを読み込み完了まで待つ
  3. 読み込み完了のJSファイルをeval()でcodeを評価する
という流れで作ればよいわけです。
JavaScriptのインクルードなんてものが出来た。
実際使ってみると、loadが終わるタイミングで上手くイベントが拾えないらしく動かない場合がある。1秒程度まてば問題なく動いている。
この方法はSVGにxlinkで動かしているスクリプトでも使えています。Canvas要素でも使えています。XMLをxml-stylesheetでXSLTを使ってHTMLに変換した場合でも使えています。(IEを除く)
2011年5月16日
「JavaScriptの簡易DB」なんて検索ワードがあったので作ってみた。
function XML_Search (XMLData,Retrieval,DataSet) {//XMLData←XMLHttpRequestオブジェクト,Retrieval←検索対象オブジェクト,DataSet←取得データオブジェクト
  var xmlDoc = XMLData.responseXML;
  var NS_object = new Object();
  var NS_AttrObject = new Object();
  var Result_object = new Array();
  var Result_cnt = 0;
  // データ取得用の要素の取得
  NS_object.XMLObject = xmlDoc;
  NS_object.NS = Retrieval[0].NS;
  NS_object.Prefix = Retrieval[0].Prefix;
  NS_object.TagName = Retrieval[0].TagName;
  var TecName_Object = ElementObject.GetNS(NS_object);
  var DATA_CK = false;
  // 検索対象要素の取得
  for (TecName_Cnt=0; TecName_Cnt<TecName_Object.length; TecName_Cnt++){
    var Extraction_FLG = false
    for (Retrieval_Cnt=1; Retrieval_Cnt<Retrieval.length; Retrieval_Cnt++){
      // 検索対象要素から値を取得
      if (Retrieval[Retrieval_Cnt].AttributeFlg) {
          NS_AttrObject.NS = Retrieval[Retrieval_Cnt].NS;
          NS_AttrObject.Prefix = Retrieval[Retrieval_Cnt].Prefix;
          NS_AttrObject.AttrName = Retrieval[Retrieval_Cnt].AttrName;
          NS_AttrObject.XMLObject = TecName_Object[TecName_Cnt];
          var Comparison_Str = AttributeObject.GetNS(NS_AttrObject);
      } else {
          NS_object.NS = Retrieval[Retrieval_Cnt].NS;
          NS_object.Prefix = Retrieval[Retrieval_Cnt].Prefix;
          NS_object.TagName = Retrieval[Retrieval_Cnt].TagName;
          NS_object.XMLObject = TecName_Object[TecName_Cnt];
          var TEXT_Object = ElementObject.GetNS(NS_object);
          var WK_Comparison_Str = TextObject.Get(TEXT_Object[0]);
          var Comparison_Str = WK_Comparison_Str[0];
      }
      // 検索対象文字かチェック
      if (Retrieval[Retrieval_Cnt].Name != "") {
          if (Retrieval[Retrieval_Cnt].CheckBox) {
              if (lastIndex(Comparison_Str, Retrieval[Retrieval_Cnt].Name)) {
                  Extraction_FLG = true;
              } else {
                  Extraction_FLG = false;
                  break;
              }
          } else {
                if (Comparison_Str ==  Retrieval[Retrieval_Cnt].Name) {
                    Extraction_FLG = true;
                } else {
                    Extraction_FLG = false;
                    break;
                }
          }
      }
    }
    // データの取得
    var WK_TecName_Object = TecName_Object[TecName_Cnt];
    var AttrName_Tag = "";
    if (Extraction_FLG) {
        Result_object[Result_cnt] = new Array();
        DATA_CK = true;
        for (DataSet_Cnt=0; DataSet_Cnt<DataSet.length; DataSet_Cnt++){
          // Elementからテキストを取得
          if (DataSet[DataSet_Cnt].DomSetFlg) {
              NS_object.NS = DataSet[DataSet_Cnt].NS;
              NS_object.Prefix = DataSet[DataSet_Cnt].Prefix;
              NS_object.TagName = DataSet[DataSet_Cnt].TagName;
              NS_object.XMLObject = WK_TecName_Object;
              var TEXT_Object = ElementObject.GetNS(NS_object);
              if (DataSet[DataSet_Cnt].TagName == "li") {
                  WK_TecName_Object = TEXT_Object;
              } else {
                  WK_TecName_Object = TEXT_Object[0];
              }
              AttrName_Tag = AttrName_Tag + DataSet[DataSet_Cnt].TagName;
          }
          // DOMの階層を下げる
          if (DataSet[DataSet_Cnt].DomGetFlg) {
              NS_object.NS = DataSet[DataSet_Cnt].NS;
              NS_object.Prefix = DataSet[DataSet_Cnt].Prefix;
              NS_object.TagName = DataSet[DataSet_Cnt].TagName;
              NS_object.XMLObject = WK_TecName_Object;
              var TEXT_Object = ElementObject.GetNS(NS_object);
              Result_object[Result_cnt][DataSet[DataSet_Cnt].TagName] = TextObject.Get(TEXT_Object[0]);
              var WK_TecName_Object = TecName_Object[TecName_Cnt];
          }
          // 属性からテキストを取得
          if (DataSet[DataSet_Cnt].AttributeFlg) {
              if (!WK_TecName_Object.length) {
                  NS_AttrObject.NS = DataSet[DataSet_Cnt].NS;
                  NS_AttrObject.Prefix = DataSet[DataSet_Cnt].Prefix;
                  NS_AttrObject.AttrName = DataSet[DataSet_Cnt].AttrName;
                  NS_AttrObject.XMLObject = WK_TecName_Object;
                  Result_object[Result_cnt][DataSet[DataSet_Cnt].AttrName] = AttributeObject.GetNS(NS_AttrObject);
              } else {
                  for (WTN_Cnt=0; WTN_Cnt<WK_TecName_Object.length; WTN_Cnt++){// RDFコンテナに対応
                       NS_AttrObject.NS = DataSet[DataSet_Cnt].NS;
                       NS_AttrObject.Prefix = DataSet[DataSet_Cnt].Prefix;
                       NS_AttrObject.AttrName = DataSet[DataSet_Cnt].AttrName;
                       NS_AttrObject.XMLObject = WK_TecName_Object[WTN_Cnt];
                       var AttrNameNo = DataSet[DataSet_Cnt].AttrName + WTN_Cnt;
                       Result_object[Result_cnt][AttrNameNo] = AttributeObject.GetNS(NS_AttrObject);
                       Result_object[Result_cnt][AttrName_Tag] = WTN_Cnt + 1;
                  }
                  AttrName_Tag = "";
              }
              var WK_TecName_Object = TecName_Object[TecName_Cnt];
          }
        }
        Result_cnt = Result_cnt + 1;
    }
  }
  if (DATA_CK) {
      return Result_object;
  } else {
      return false;
  }
}
細かく説明するのが面倒なので割愛。JavaScriptの簡易DB-1で作った関数を使ってます。
戻り値は、Array()に、連想配列で戻ります。連想配列の添え字は、タグ名になってます。
RDFコンテナに対応に対応した場合、値を取得せずに要素を辿ります。辿った分だけタグ名が追加された連想配列の添え字に、該当する要素が何個あるのか格納してあります。値を取得する場合、要素名+cntで取得してください。
2011年5月16日
「JavaScriptの簡易DB」なんて検索ワードがあったので作ってみた。
検索項目の指定
	var XML_Retrieval = new Array();
	XML_Retrieval[0] = new Object();
	XML_Retrieval[0].NS = "http://www.geocities.jp/sendaituri/owl/fncmjp.xml#"
	XML_Retrieval[0].Prefix = "観察";
	XML_Retrieval[0].TagName = "学名";

	XML_Retrieval[1] = new Object();
	XML_Retrieval[1].NS = "http://www.geocities.jp/sendaituri/owl/fncmjp.xml#"
	XML_Retrieval[1].Prefix = "観察";
	XML_Retrieval[1].AttrName = "標準和名";
	XML_Retrieval[1].AttributeFlg = true;

	XML_Retrieval[2] = new Object();
	XML_Retrieval[2].NS = "http://www.geocities.jp/sendaituri/owl/fncmjp.xml#"
	XML_Retrieval[2].Prefix = "観察";
	XML_Retrieval[2].TagName = "分類";
	XML_Retrieval[2].AttributeFlg = false;
	var Form_obj = ElementObject.ID("zform");
	XML_Retrieval[1].Name = Form_obj.zselect1.value;
	XML_Retrieval[1].CheckBox = Form_obj.check1.checked;
	XML_Retrieval[2].Name = Form_obj.zselect2.value;
	XML_Retrieval[2].CheckBox = Form_obj.check2.checked;
  1. 0行目は、検索するRDFクラスのタグを指定します。
  2. .NS:該当する名前空間のURL
  3. .Prefix:接頭辞
  4. .TagName:タグ名
  5. .AttributeFlg:取得する値が属性なtrue,要素ならfalse
  6. 1行目以降は、検索対象の指定になります。上記項目に以下の項目を追加
  7. .Name:比較対照の文字列
  8. .CheckBox:false→完全合致,true→部分一致
データ取得項目の指定
	var XML_Setting = new Array();

	XML_Setting[0] = new Object();
	XML_Setting[0].NS = "http://www.geocities.jp/sendaituri/owl/fncmjp.xml#"
	XML_Setting[0].Prefix = "観察";
	XML_Setting[0].AttrName = "標準和名";
	XML_Setting[0].DomSetFlg = false;
	XML_Setting[0].DomGetFlg = false;
	XML_Setting[0].AttributeFlg = true;

	XML_Setting[4] = new Object();
	XML_Setting[4].NS = "http://www.geocities.jp/sendaituri/owl/fncmjp.xml#"
	XML_Setting[4].Prefix = "観察";
	XML_Setting[4].TagName = "画像";
	XML_Setting[4].DomSetFlg = true;
	XML_Setting[4].DomGetFlg = false;
	XML_Setting[4].AttributeFlg = false;

	XML_Setting[5] = new Object();
	XML_Setting[5].NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	XML_Setting[5].Prefix = "rdf";
	XML_Setting[5].TagName = "Bag";
	XML_Setting[5].DomSetFlg = true;
	XML_Setting[5].DomGetFlg = false;
	XML_Setting[5].AttributeFlg = false;

	XML_Setting[6] = new Object();
	XML_Setting[6].NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	XML_Setting[6].Prefix = "rdf";
	XML_Setting[6].TagName = "li";
	XML_Setting[6].DomSetFlg = true;
	XML_Setting[6].DomGetFlg = false;
	XML_Setting[6].AttributeFlg = false;

	XML_Setting[7] = new Object();
	XML_Setting[7].NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	XML_Setting[7].Prefix = "rdf";
	XML_Setting[7].AttrName = "resource";
	XML_Setting[7].DomSetFlg = false;
	XML_Setting[7].DomGetFlg = false;
	XML_Setting[7].AttributeFlg = true;
  1. .NS:該当する名前空間のURL
  2. .Prefix:接頭辞
  3. .TagName:タグ名(*1)
  4. .AttrName:属性名(*1)
  5. .DomSetFlg:DOMをSETする場合true,しない場合false(*2)
  6. .DomGetFlg:要素の値を取得する場合true,しない場合false(*2)
  7. .AttributeFlg:属性値を取得する場合true,しない場合false(*2)

*1、*2はいずれか一つを指定。AttributeFlgを指定した場合、AttrNameを指定すること

「JavaScriptの簡易DB-3」のサンプルはこの条件でデータを取得します。
2011年5月18日
JavaScriptでinclideぽっいのを作ってみた。
function include_JS (IncludFile) {
  XMLhttp[IncludFile.Name] = xmlcreateXMLHttp();
  IncludeFile = IncludFile.URL   IncludFile.Name   ".js";
  if (XMLhttp[IncludFile.Name] != false) {
      XMLhttp[IncludFile.Name].open("GET",IncludeFile,false);
      XMLhttp[IncludFile.Name].send("");
      return XMLhttp[IncludFile.Name].responseText;
  }
}
var IncludeJS = include_JS;
IncludFile.URLはJSファイルが格納されているフォルダーのURL。IncludFile.Nameは拡張子を抜いたJSファイル名です
指定したJSをXMLHttprequestでテキストで返すスクリプトです。
var JS_ReadXmlLC = false;
var IncludeFile = new Object();
IncludeFile.Name = "XXXXX";
IncludeFile.URL = "http://musimusi.g.ribbon.to/JavaScript/";
JS_ReadXmlLC = IncludeJS(IncludeFile);
do{
}while(JS_ReadXmlLC == false);
eval(JS_ReadXmlLC);
IncludFile.URLはJSファイルが格納されているフォルダーのURL。IncludFile.Nameは拡張子を抜いたJSファイル名です
戻り値が返る変数をfalseにしておきます。IncludeJSを読み込んでいる間も読み込んだJavaScriptの処理は先に進んでしまうため 、do-whileで戻り値があるまで、ループしてます。
戻り値が帰ってきたら、evalで評価します。
使う直前で読み込まないと対象のスクリプトは使えなくなります。なので、PHPやXSLTのIncudeとはかなり違います。
しかも、スクリプトが動く度読み込みのリクエストが発生します。
メリットはHTMLファイルにscript要素を追加しなくてすむことです。DOMを使ってもできそうなのですが、DOMでscript要素を追加した場合、自分の意図したタイミングで評価されず、うまくスクリプトが動かない場合がありそうです。
2011年5月16日
「JavaScriptの簡易DB」なんて検索ワードがあったので作ってみた。
前回作ったのだが「複数文書を読んで検索」の設定を考えるのが面倒で諦めたのだが、考え方を変えてみた。
DOM操作でなく、XSLTでJSONに変換してしまえば、JavaScriptだろうが、PHPだろうが、xsltprocessor()さえ使えれば環境に関係なくデータ変換ができる。
XSLTのDocument()であれば、XMLHttpRequestを使うより簡単に使える。あとで拡張するのも楽である。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:rss="http://purl.org/rss/1.0/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:dcterms="http://purl.org/dc/terms/"
  xmlns:wot="http://xmlns.com/wot/0.1/"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:wn="http://xmlns.com/wordnet/1.6/"
  xmlns:doas="http://purl.org/net/ns/doas#"
  xmlns:ex="http://example.org/stuff/1.0/"
  xmlns:cc="http://creativecommons.org/ns#"
  xmlns:ccm="http://web.resource.org/cc/"
  xmlns:fncm="http://www.geocities.jp/sendaituri/owl/fncm.xml#"
  exclude-result-prefixes=" xsl rdf atom rss dc dcterms wot foaf wn doas ex">
  <xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="application/json"/>
  <xsl:template match="/">
    <xsl:text>{"SerchData":[</xsl:text>
    <xsl:call-template name="rdf_fncm">
      <xsl:with-param name="sflg" select="1"/>
    </xsl:call-template>
    <xsl:text>]}</xsl:text>
  </xsl:template>  
  <xsl:template name="rdf_fncm">
    <xsl:param name="sflg"/>
    <xsl:if test="count(//fncm:TechnicalName) >= $sflg">
      <!-- technicalName -->
      <xsl:if test="contains('1', $sflg)">
        <xsl:text>{"technicalName":"</xsl:text>
      </xsl:if>
      <xsl:if test="$sflg >= 2">
        <xsl:text>,{"technicalName":"</xsl:text>
      </xsl:if>
      <xsl:value-of select="substring-after(//fncm:TechnicalName[$sflg]/@rdf:about, 'technicalname:')" />
      <xsl:text>"</xsl:text>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/@fncm:JapaneseName) = 1">
        <xsl:text>,"JapaneseName":"</xsl:text>
        <xsl:value-of select="//fncm:TechnicalName[$sflg]/@fncm:JapaneseName" />
        <xsl:text>"</xsl:text>
      </xsl:if>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/fncm:Classification) = 1">
        <xsl:text>,"Classification":"</xsl:text>
        <xsl:value-of select="//fncm:TechnicalName[$sflg]/fncm:Classification" />
        <xsl:text>"</xsl:text>
      </xsl:if>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/fncm:originate/fncm:ScientificName) = 1">
        <xsl:text>,"ScientificName":"</xsl:text>
        <xsl:value-of select="//fncm:TechnicalName[$sflg]/fncm:originate/fncm:ScientificName"/>
        <xsl:text>"</xsl:text>
      </xsl:if>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/fncm:originate/fncm:NipponName) = 1">
        <xsl:text>,"NipponName":"</xsl:text>
        <xsl:value-of select="//fncm:TechnicalName[$sflg]/fncm:originate/fncm:NipponName"/>
        <xsl:text>"</xsl:text>
      </xsl:if>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/fncm:Image) = 1">
        <xsl:text>,"Image":[</xsl:text>
        <xsl:for-each select="//fncm:TechnicalName[$sflg]/fncm:Image/rdf:Bag/rdf:li">
          <xsl:text>{"title":"</xsl:text>
          <xsl:value-of select="@fncm:title" />
          <xsl:text>",</xsl:text>
          <xsl:text>"date":"</xsl:text>
          <xsl:value-of select="@dc:date" />
          <xsl:text>",</xsl:text>
          <xsl:text>"resource":"</xsl:text>
          <xsl:value-of select="@rdf:resource" />
          <xsl:choose>
            <xsl:when test="position()=last()">
              <xsl:text>"}</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>"},</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
        <xsl:text>]</xsl:text>
      </xsl:if>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/fncm:treaty/rdf:Bag/rdf:li) >= 1">
        <xsl:text>,"treaty":[</xsl:text>
        <xsl:for-each select="//fncm:TechnicalName[$sflg]/fncm:treaty/rdf:Bag/rdf:li">
          <xsl:text>{"title":"</xsl:text>
          <xsl:value-of select="@fncm:title" />
          <xsl:text>",</xsl:text>
          <xsl:text>"resource":"</xsl:text>
          <xsl:value-of select="@rdf:resource" />
          <xsl:choose>
            <xsl:when test="position()=last()">
              <xsl:text>"}</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>"},</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
        <xsl:text>]</xsl:text>
      </xsl:if>

      <xsl:if test="count(//fncm:TechnicalName[$sflg]/fncm:RedDataBook/rdf:Bag/rdf:li) >= 1">
        <xsl:text>,"RedDataBook":[</xsl:text>
        <xsl:for-each select="//fncm:TechnicalName[$sflg]/fncm:RedDataBook/rdf:Bag/rdf:li">
          <xsl:text>{"Regional":"</xsl:text>
          <xsl:value-of select="@fncm:Regional" />
          <xsl:text>",</xsl:text>
          <xsl:text>"RDBcategory":"</xsl:text>
          <xsl:value-of select="@fncm:RDBcategory" />
          <xsl:choose>
            <xsl:when test="position()=last()">
              <xsl:text>"}</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>"},</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
        <xsl:text>]</xsl:text>
      </xsl:if>
      
      <xsl:variable name="habitf" select="document(//fncm:TechnicalName[$sflg]/fncm:AboutHabit/@fncm:XMLdocument)"/>
      <xsl:call-template name="owl_Habit_about">
        <xsl:with-param name="rcuri" select="substring(//fncm:TechnicalName[$sflg]/fncm:AboutHabit/@rdf:resource, 2)"/>
        <xsl:with-param name="owlwk" select="$habitf"/>
      </xsl:call-template>
      <xsl:text>}</xsl:text>
      <!-- ループ -->
      <xsl:call-template name="rdf_fncm">
        <xsl:with-param name="sflg" select="$sflg + 1" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <xsl:template name="owl_Habit_about">
    <xsl:param name="rcuri"/>
    <xsl:param name="owlwk"/>
    <xsl:for-each select="$owlwk//fncm:Habit">
      <xsl:if test="count(@rdf:ID) = 1">
        <xsl:if test="contains(@rdf:ID, $rcuri)">
          <xsl:if test="count(fncm:habitat) = 1">
            <xsl:text>,"habitat":"</xsl:text>
            <xsl:value-of select="fncm:habitat"/>
            <xsl:text>"</xsl:text>
          </xsl:if>
          <xsl:if test="count(fncm:origin) = 1">
            <xsl:text>,"origin":"</xsl:text>
            <xsl:value-of select="fncm:origin"/>
            <xsl:text>"</xsl:text>
          </xsl:if>
          <xsl:if test="count(fncm:season) = 1">
            <xsl:text>,"season":"</xsl:text>
            <xsl:value-of select="fncm:season"/>
            <xsl:text>"</xsl:text>
          </xsl:if>
          <xsl:if test="count(fncm:feature) = 1">
            <xsl:text>,"feature":"</xsl:text>
            <xsl:value-of select="fncm:feature"/>
            <xsl:text>"</xsl:text>
          </xsl:if>
          <xsl:if test="count(fncm:use) = 1">
            <xsl:text>,"use":"</xsl:text>
            <xsl:value-of select="fncm:use"/>
            <xsl:text>"</xsl:text>
          </xsl:if>
          <xsl:if test="count(fncm:attention) = 1">
            <xsl:text>,"attention":"</xsl:text>
            <xsl:value-of select="fncm:attention"/>
            <xsl:text>"</xsl:text>
          </xsl:if>
        </xsl:if>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
「生き物についての簡単な説明」のXMLをJSONに変換する専用XSLTです。JavaScriptの簡易DBで示したXMLをJSONに変換します。
あとは、連想配列にしてしまえば利用はかんたんです。「JSONにしてしまえば良い」なんて発想は今までなかったです。
これはべんりだなぁ。
2011年6月14日
HTML5のFORM要素はbutton要素でsubmitを使わないと有効でない場合が多くXMLHttpRequestを使った場合使い難い。JavaScriptでいイベントを拾ってXMLHttpRequestした場合、反応しないのである。
そんな中、autocomplete属性はsubmitに関係なく使えるので使ってみた。INPUT要素のtype=textにoptionで指定した語句を入力してくれるのである。
select-optionは、検索する場合、必ずリストBOXを出して選択しなくてはならないのだが、autocomplete属性の指定したinput-optionは、必要なら選択すればよいのである。必要なければ、キーボードから入力できるのである。
入力補助にも使えます。選んだリストは修正可能なので選択後に、文字の追加・削除も可能です。
生き物検索 XSLT-PHP-JavaScrpt版で実験してます。 意外と使いやすいです。FX4,Operaが対応しています。
2011年7月4日
「Web Storage」というものがある。「データをブラウザ側に蓄積する仕組み」だそうだ。「Cookieより大きなデータを蓄積できる」みたいです。使い道はいろいろありそうです。
「getItem(key)」でデータの取り込み、「setItem(key, value)」でデータの書き込み、「removeItem(key)」で該当項目の削除ができます。それに、ストレージ領域が変化したときに発生する「storage イベント」があるそうです。イベントは面倒なのでパス。データの読み書きだけを行う。
基本的に指定したKEYにテキストデータを書き込むだけの仕様である。扱うのがテキストならばJSONが使える。データの格納はJSONで記述したデータを使う。そうすれば、ひとつのKEYに複数のデータを埋め込める。
なんとなく生き物検索-(XMLデータ検索)に埋め込んでみました。
に使ってます。
JSONと組み合わせることで、真価を発揮する仕様だなぁと感じた。
最近のJavaScript周りの仕様はJSONを使うことがベースにあると感じる。
2011年7月5日
Web Storageなのだが、非常に面白いと思います。「個人の感想などを製作者が管理しないで、個人が管理する」のが、Web Storageなのだと感じた。
個人識別するID等をなしで、個人をある程度特定してデータを入れておける仕組みです。あまり重要でないデータなら、このやり方は簡単です。開発も楽です。
この仕組みの問題は、開発者がデータの管理をしない・できないところにあります。
たとえば、公共のパソコンでWeb Storageにデータを書き込み、犯罪行為等の連絡に使われた場合、開発者がしっかりログをとっておかないかぎり、その内容が表にでることは無いと思います。
悪意のある人が、Web Storageのみの、プログラムを作った場合なんか、いくらWebを検索してもなにも情報がでません。けど情報の伝達はできます。
ブラウザには、「Web Storage」のON/OFFができるようにしてもらわないと困ります。
2011年7月12日
YEAR OF THE CATがあった。CSSの解説があったりする「ほーむぺーじ」である。まぁ、「迷惑なサンプル」を配布する部類に属する「ほーむぺーじ」になりつつあるぺーじです。

このページを作った動機。最近スタイルシートを使った「タグ」等を「配布」しているサイトを良く見かけますが、Win+ie以外ではレイアウトが崩れて見れない物が、やたらと多い。(しかもテーブルでレイアウト+CSSで装飾しながら)Win+ieでしか閲覧できないサイトを作るのは当人の勝手ですが、Win+ieでしか表示されない「タグ」や「テンプレート」を「配布」するなんてこれはもう公害です。 ということで、このページは公害対策用に作成しました。

この意見には賛成です。まったくもってその通りです。
問題は次のページです。スタイルシートによる崩れない 2カラム 3カラム・レイアウトの紹介です。floatを使った段組の方法が紹介されてます。floatは回り込みの指定であって、段組の指定ではない。段組を作る指定がないCSS2.1で段組を作る苦肉の策、別の言い方をすれば間違った使い方なのである。まぁ、CSS2.1では段組を作る指定が無かったからしょうがない。CSS3で段組ができるようになった場合、このページは間違いを配布する公害になってしまう。
過去の記事の弊害は多々ある。自分が公開した文書は過去のものも気をつけなければならない。
2011年7月19日
4月から「JavaScriptによる簡易データ検索」なるものを作っていたのだが、最終的には「簡易」が取れてしまうようなスクリプトになってしまった。
初めはXML文書を「名前」と「目科属」での検索するだけだった。作ってみると、複数のXML文書で1つのデータになるような構成の場合の処理が上手くいかないのである。
複数にの文書のデータを1つにまとめる際、基本になるXML文書に記述してあるURLに従ってデータを取得したい。その制御を考えると「ちょっとやりたくない」となってしまった。
しかし、複数のXML文書からなるデータの検索はやりたい。「出来ない」のでなく「面倒くさい」だけなのだから「簡単な方法」が見つかれば良いだけの話である。
そう考えると、XML文書を変換するには、XSLTがある。XMLをXSLTでJSONに変換してしまえば、比較的簡単にデータを扱える。図鑑表示のXSLTをJSONデータ作成用に作り変えれば、そんなに手間は掛からない。検索・表示はXMLの検索を直せばよい。
こんどは、XML図鑑と同じデータを使うことになると、「都道府県・レッドデータカテゴリー」と「条約・法律等」の検索がしたくなる。条約名やレッドデータカテゴリーは「わかりにくい」。選択できて自分で変更できるのがベストです。
HTML5の仕様を見ていると、autocomplete属性なるものがある。input要素にテキストを選択して入力できる。FirefoxとOperaが使える。これは使うしかないでしょう。
autocomplete属性が使えるなら、「Web Storage API」と連携して、自分が入力した履歴を記録して選択できるようにする。「Web Storage API」なら、PCなどの端末機のブラウザにデータを記録するので、ある程度「個人向けのデータ」として使える。
「個人でのデータ」として使えるなら、検索結果に「和名」をクリックすると「個人メモ」を入力できるようにすれば面白い。
個人メモを入力できるなら、携帯端末で「鳥を見付けたらその場所を該当する鳥に関連付けてメモ」も面白い。「GeoLocationAPI」で位置情報を取得して記録すれば良い。
携帯端末で、カタカナ変換するのが面倒になる。「ひらがな」をスクリプトで「カタカナ」に変換して検索でもよいのだが、面白くない。同じ検索フォームで「学名」でも「地方名」でも「漢字」でも「ひらがな」でも検索したい。
「類語・同義語」データを作り、「類語・同義語」から「検索文字」に変換する。JavaScriptの連想配列を使えば簡単なので、JSON形式でデータを作成する。
3ヶ月でこんな感じです。やりたいことは大体詰め込んだとおもいます。
JavaScriptだけで随分なことができるようになったと思います。
2011年8月22日
7月19日に「類語・同義語」を作ってからのその後の話。
複数のXMLを1つにまとめると、JavaScriptでのデータ検索が遅くなってしまう。XMLデータは、「鳥類」「魚類」「虫類」「その他」に分かれているので、「生物の分類」がはっきりしていれば、該当するXML文書を読み込めばよい。
従って、「和名」からXML文書を示すデータと、「生物の分類」からXML文書を示すデータを作ればよい。そのデータに該当すればそのデータが示すXMLのみを読み込めばよい。
「類語・同義語」は作ったが、実際FORMに文字を入れてみると、「生き物の名前の一部」しかわからない。その名前も「標準和名」かどうかもわからない。ようするに「マッチ」しないのである。
せっかく作ったのに目的を達成できていない。なので「曖昧選択」なるものを作ってみた。
検索窓に文字をいれると、「類語・同義語」に登録してある文字の一部と「マッチ」した、生き物の名前を表示、選択できるようにしてみた。
せっかく「類語・同義語」があるのに、それを見ることが出来ないので、おまけ機能「異名検索」を作ってみた。和名から異名の一覧を表示するものです。
検索をしていると、和名が「~ガラス」や「~ガエル」となる場合がある。「曖昧選択」で「カエル」と入力しても「マッチ」しないで「該当なし」になってしまう。「曖昧選択」なのに選択しない。
「類語・同義語」に「~カエル」を登録する。そうすると、「異名検索」で「~カエル」が出てしまい格好がわるい。「ガエル」と「カエル」を同じに扱う用にしてして、Keyとデータが同じ場合出力しないようにする。
今後は、データが大きくなった「虫類」のファイルの分割を行って終了かなぁ。
2011年8月23日
Android についてXSLTについて検索している人が多い。この際「なんとなく趣味のページ」で集めた情報を書いておく。
Android 1.6: localStorage,GeoLocation,XSLTProcessor,CrossDocumentMessaging
Android 2.2.X: XSLTProcessor,localStorage,GeoLocation,CrossDocumentMessaging
Android 2.2.4: Google Web Preview localStorage,GeoLocation,XSLTProcessor,CrossDocumentMessaging
Android Opera Mini: localStorage,GeoLocation,XSLTProcessor,CrossDocumentMessaging
ipad: localStorage,GeoLocation,XSLTProcessor,CrossDocumentMessaging
iphon: localStorage,GeoLocation,XSLTProcessor,CrossDocumentMessaging
Canvas,SVG,HTML5,CSS3については、手元に端末がないので不明
2011年8月30日
検索に「xslt 流行らない理由」とある。私のページでは、XSLTが無いと困るくらい使っているのだが……。
XSLTの利点はXMLを別の形式に変更できるところにある。従ってXMLがないと無用なのである。
「流行る」ためには、何もしらない人が簡単に使える必要がある。何も知らない人が「XML」を使いこなすとは思えない。
XMLを使いこなそうと思ったらかなりの勉強が必要です。XMLの仕様・言語での取り扱いかた等色々あります。
しかし、XSLTはXMLのデータを使おうと思った場合、かなり強力なツールになります。
XSLTProcessorが使えた場合、XMLをJSONに変換して、結果を連想配列にして使うことが出来ます。言語でXMLを扱う勉強をしなくてもXMLを扱うことが可能です。
「xslt 流行らない理由」は「XML自体が流行ってない」そして「開発者の発想が貧弱」だからだと思います。
「xslt 流行らない理由」を考えるまえに、有効な使い方を考えてください。
2011年9月8日
「生き物図鑑・検索」を作っているのだが、「なんとなく趣味のページ」では、釣った魚や撮影した鳥の年度別一覧のデータを作成して公開している。「なんとなく趣味のページ」では、過去~現在までに見つけた生き物のデータがある。
生き物のデータは、「生き物検索」に使っているが、「釣った魚や撮影した鳥の年度別一覧のデータ」のデータを、検索データに取り込めば、ちょっと面白い。見つけた場所や日時。釣った魚の仕掛け情報も表示できる。
データの連携は「標準和名」を使えばよい。それでデータの連携ができる。PHPであればサーバーを関係なくデータを取り込める。後は、変換用のXSLTを作ればよい。それで、データ変換して使えばよい。
観察場所をクリックすると、場所・日時等のデータが出力できるようになった。基本画面で、表示する画像を減らすことができる。しかも、いままで出せなかった情報も出せるわけだ。
こう考えると、XMLでデータを提供すると、勝手に使ってもらってなにか別のモノになっている可能性がある訳だ。ちょっと面白い。
2011年9月13日
CSSにdisplayプロパティがある。noneの指定は「何もないものとして表示されます。」と説明されている。
この「表示」が問題で、本当に表示だけなのですか?となる場合がある。
display:noneを指定した要素は、displayプロパティの変更以外なにも出来なくなることがある。display:noneを指定している要素に要素を追加して表示させる場合、display:blockなどに変更してから追加しないと、「表示しない」となる場合がある。
「なにもないから表示できない」って挙動がただし表現かもしれません。
表示はしたくない、けど使いたい要素があります。(クロスドキュメントメッセージングとかです。)表示したくないからdisplay:noneを使うと、要素自体が無いものと扱われて何も出来ないってことになってしまう場合があるます。
その場合は「visibility : hidden」を使い、非表示扱いにします。これは「表示しない」指定なので、要素は存在します。
JavaScriptが上手く動かない場合、CSSのdisplayを見直したほうが良い場合があります。
2011年9月28日
「Indexed Database API」って、Web StorageにJSONデータを書き込んでいるようにしか見えない。「なくてもいいじゃね。現状でも出来るしくみだよね。」と思える。
例えばKEYの設定は{"KEY値":{"項目1":"データ1","項目2":"データ2",……},"KEY値":{"項目1":"データ1","項目2":"データ2",……}}でKEYの設定ができる。あとは、getItemでデータを取得して、evalで連想配列にしてしまえばよい。連想配列にしてしまえば、deleteもsortもできます。まぁ、アクセスが楽になるくらいで、「なくてもできるよね」となってしまう。
自力で「Web StorageにJSONデータを書き込む」ほうが、いろいろ応用ができます。「Indexed Database API」のほうが、書き込めるデータが多いのならそれなりのメリットです。しかし、「Indexed Database API」を使うのは、「発想が貧弱なだけじゃない」と思います。
2011年10月5日
やはり、検索するたびにデータ通信をしてしまうとボタンを押してから表示までに時間が掛かってしまう。一度データを読み込んだらそのデータをどこかに保存して使えば通信をする必要がなくなる。
「localStorage」は、データが残ってしまって、ブラウザにあるデータが最新なのか確認しなくてはならない。それは面倒くさい。
どうしようかと思っていたら「sessionStorage」があることに気づいた。ブラウザでアクセスするとデータを格納できる仕組みで、ブラウザを閉じるとデータも消失する。
そうすると、「ページにアクセス→「sessionStorage」にデータがあるか確認→データが無い場合データの読み込み。→「sessionStorage」の内容でデータ検索。」という流れで処理ができる。
初回の読み込みは遅いが、2回目以降の検索はとても早い。データも最新の状態で検索できる。
HTML5の機能を使うと面白いモノが作れます。
2011年10月7日
「Indexed Database API」の否定的に書いた。「どの程度わかっていて否定的なんだ」といわれそうなので、サンプルページを作ってみた。
Indexed Database APIによるデータベースへっぽこプログラマーの日記 とかをぱくってきて作成した。
Index DB Sample.で公開。検索KEYを複数にしたい場合どうすればよいのだ?仕様書を見ると「ある文字列が含まれていたら」が出来無そう。
KEYがあればデータを持ってくるのが「Index Database」ならば、しょうがない。やはり、「Web Storage」にJSONで格納して検索するのと大差ないように思える。
せめて複数KEYで検索できればと思うのだが、やりかたがわからない。使い道が考え付かない。
2011年10月19日
検索ワードで「IE8 リファラ」が相変わらず多い。ちょっと気になったので「HTML5 における HTML4 からの変更点」(2011年5月25日付 W3C 草案 (Working Draft))を確認した。
Window オブジェクトの opener アトリビュートは、target="_blank" や rel="noreferrer" なリンクから開かれたページでは存在しないようになりました。(強調ムシムシ)となってます。
HTML5のWDによれば、target="_blank"rel="noreferrer"以外の場合はリファラは残るように思えます。
JavaScriptはHTMLではないので、この仕様が適応されるのかわかりません。new windowはHTML5に倣えば、リファラを残さないかもしれません。
HTML5はまだWDなのでこれからも仕様が変わっていくと思います。過去のブラウザは諦めましょう。
WDをもとにブラウザを作るなら、頻繁に更新しないとダメだと思います。
2011年10月31日
『JSONオブジェクトをstringfyを使わずにJSON形式文字列に変換する』なんて検索があった。『JSONオブジェクト』なるものが不明です。JSONとは『JavaScriptにおけるオブジェクトの表記法をベースとしたデータ記述方法』なので、JSON形式文字列に変換前はobject(連想配列)です。特別にJSON用のオブジェクト作るコードがあるわけではなく、new Object()new Arraryで作られたオブジェクトが対象になります。
JSONの表記方法は簡単です。「配列」は [] で表記、「object」は {} で表します。[]の中は、value(2重引用符に囲まれた文字列、数値、true、false、null、オブジェクト、配列)が入ります。複数値がある場合,(カンマ)を使います。 「object」は {} で表します。{}の中身は、「string : value」(2重引用符に囲まれた文字列 : value)が入り、複数値がある場合,(カンマ)を使います。
たまに、JSONの説明でvar str = "{x:1, y:2}";なんて書いてありますが間違いです。var str = '{"x":1, "y":2}';が正解です。よく見かけるので真似しないでください。
この表記が出来ないオブジェクトは対象外です。JSON形式にする前に取り除きましょう。
上記を踏まえてJavaScriptを作ってあげれば良いわけです。Arrayはfor文でObjectはfor(~ in ~)文でデータを変換すればよいのです。ただし、オブジェクトの中に配列があり、その配列の中にオブジェクトがありなんてオブジェクトを変換出来るJavaScriptを作るのは大変です。
自前で作らないのであれば、「prototype.jsを使う」、「jQueryを使う」でも良いのでは。勉強したいのなら、JSON2のstringfyでなにをやっているのかソースを見たほうが良いとおもいます。
2011年11月22日
JSONを記録するPHPを作った。
{"変数-1":[{ },{ }],"変数-2:[{ }],~}
{"変数-1":[{"KEY":"変数-1で一意の値",~},{"KEY":"変数-1で一意るの値",~}],
"変数-2":[{"KEY":"変数-2で一意の値",~}],~}
のいずれかで記録できます。
{"変数-1":[{ },{ }],"変数-2:[{ }],~}
は変数で指定した名前のオブジェクトに、データをためていくだけのJSON形式です。
{"変数-1":[{"KEY":"変数-1で一意の値",~},{"KEY":"変数-1で一意るの値",~}],
"変数-2":[{"KEY":"変数-2で一意の値",~}],~}
は変数で指定した名前のオブジェクトに、KEYを付加してデータの変更をできるようにしたJSONです。
ただし、KEYは自分で指定するようにしています。date("Y/m/d H:i:s", date("U"))で自動的にKEYにしてしようかと思ったのですがやめました。必要なら自分でおくればいいわけだし。
この方法の長所は
  1. DBのアプリが必要ない
  2. CSVよりアクセスが楽
  3. 項目をプログラムを作る時に決めることができる
  4. 簡単な検索が可能
  5. 生データを見たとき、UTF-8でコード化されていてデータがわかりにくい
長所があれば短所もあります。
  1. 書き込みのとき、ファイル全体を読み込む必要がある
  2. 複雑な検索はプログラムで工夫する必要がある
  3. 生データを見たとき、UTF-8でコード化されていてデータがわかりにくい
実ファイルに書かずに、常時メモリにオブジェクトとしてデータが存在できたらいいのになぁ。と思う。そうすれば、「ファイル全体を読み込む」必要がなくなる。バックアップで実ファイルにJSON形式で記録するのが、本来の使い方だよなぁ。と思う。
SQLなら、「SELECT WHERE」で出来ることが出来ません。まぁ、APIがないのだからしょうがない。
既存のPHPフレームワークに使いたいKVSの機能が無かったので自主作成です。このページのコメントに使用してます。
そのうち、他のページにも流用させよう。
2011年11月24日
PHPでJSONを使ったデータの管理スクリプトを作っているのだが、JSONのデータから必要なデータを取り出した連想配列をソートする必要があった。
データを管理しているPHPクラスは、データの入出力しかしないので、データを受け取ったPHPスクリプトで並び替えをする。連想配列のソートのやり方がわからない。usortとかみても面倒くさい。もっと簡単な方法はないものかと調べてみると、array_multisortなんてものがある。
array_multisort(配列-1, ソート方法, 配列-2);と指定します。配列-1の内容で、配列-2もソートされます。ようするに、配列-1にSortKEYにしたい連想配列の値をいれた配列を用意して、配列-2をソートされる連想配列を指定します。すると、配列-1の内容で配列-2がソートされます。
複数KEYを指定することも可能。便利なきのうです。
2011年11月25日
データを{"変数-1":[{ },{ }],"変数-2":[{ }],~}の形のJSON形式で記録するPHPクラスです。データは連想配列で渡してください。
NewData:追加・変更データ。FileUrl:読み込むファイルの位置。process:削除の場合DEL。KeyText:変数にあたるテキストです。
変数を消すことは出来ません。
NewDataにKEYを指定した場合、指定されたKEYがある場合、削除・変更されます。無い場合追記です。
class KVS_Module {
  public    $JSON_Text;
  protected $KVS_Data;
  protected $new_memberJSON;
  protected $FileName;
  protected $process;
  protected $KeyText;
  protected $members;
  protected $New_JSON_Object;
  protected $FileUrl;
  private   $key;
  private   $value;
  private   $Read_Text;
  private   $JSON_Object;
  private   $DB_Data;
  private   $output;
  function __construct ($in1 = ""){
    $this -> KVS_Data = $in1;
    foreach($this -> KVS_Data as $this -> key => $this -> value ){
      switch($this -> key) {
        case "NewData":
          $this -> new_memberJSON = $this -> value;
          break;
        case "FileUrl":
          $this -> FileName = $this -> value;
          break;
        case "process":
          $this -> process = $this -> value;
          break;
        case "KeyText":
          $this -> KEYText = $this -> value;
          break;
      }
    }
  }

  function KVS_Data_Get() {
    if ($this -> FileName != "") {
      $this -> FileUrl = "ファイルの場所";
      if ( !file_exists( $this -> FileUrl )) {
        touch( $this -> FileUrl );
        chmod($this -> FileUrl,0666);
      }
      $this -> Read_Text = file_get_contents($this -> FileUrl);
      $this -> JSON_Object = json_decode($this -> Read_Text, true);
      if (!$this -> JSON_Object[$this -> KEYText]) {
        return 'No Data';
      }
      $this -> DB_Data = $this -> JSON_Object[$this -> KEYText];
      $this -> JSON_Text = json_encode($this -> DB_Data);
      return $this -> JSON_Text;
    }
  }

  function KVS_Data_Put() {
    $this -> FileUrl = "ファイルの場所";
    if ( !file_exists( $this -> FileUrl )) {
      touch( $this -> FileUrl );
      chmod($this -> FileUrl,0666);
    }

    $this -> JSON_Text = file_get_contents($this -> FileUrl);
    $this -> JSON_Object = json_decode($this -> JSON_Text, true);

    $this -> New_JSON_Object = json_decode($this -> new_memberJSON);
    if (!$this -> JSON_Object[$this -> KEYText]) {
      $this -> JSON_Object[$this -> KEYText][] = (array)$this -> New_JSON_Object;
      $this -> New_JSON_Object = 'NOT DATA';
    }
    $this -> DB_Data = $this -> JSON_Object[$this -> KEYText];

    //stdClass objectを連想配列にキャスト
    foreach($this -> DB_Data as $this -> value){
      $this -> members[] = (array)$this -> value;
    }
    $KVS_Match_object = new KVS_match_array($this -> members,$this -> New_JSON_Object);
    $this -> output = $KVS_Match_object -> match_array($this -> process);
    //$output = match_array($this -> members,$this -> New_JSON_Object,$this -> process);

    $this -> JSON_Object[$this -> KEYText] = $this -> output;
    //JSONフォーマットへ変換して書き込み
    if (is_writable($this -> FileUrl)) {
      $JSON_File = fopen($this -> FileUrl, 'w');
      fwrite($JSON_File,json_encode($this -> JSON_Object));
      fclose($JSON_File);
    }
  }
}
class KVS_match_array {
  public    $Original;
  protected $Updating;
  protected $Processing;
  private   $key;
  private   $value;
  private   $KeyFLG;
  private   $KeyData;
  private   $pointer;
  private   $point;
  function __construct ($in1 = "", $in2 = "", $in3 = ""){
    $this -> Original = $in1;
    $this -> Updating = $in2;
    $this -> Processing = $in3;
  }
  function match_array() {
    if ($this -> Updating != 'NOT DATA') {
      $this -> KeyFLG = false;
      foreach($this -> Updating as $this -> key => $this -> value ){
        if ($this -> key == 'key') {
          $this -> KeyData = $this -> value;
          $this -> KeyFLG = true;
        }
      }
      $i = 0;
      if ($this -> Original) {
        $this -> KeyFLG = false;
      }

      if ($this -> KeyFLG) {
        foreach($this -> Original as $this -> value){
          if (!$this -> value['key']) {
            $this -> KeyFLG = false;
          } else {
              if($this -> value['key'] == $this -> KeyData) {
                $this -> pointer = $this -> point;
                $this -> KeyFLG = true;
                $this -> point  ;
              }
          }
        }
      }
      if ($this -> Processing == 'DEL') {
        unset($this -> Original[$this -> pointer]);
      } else {
        if($this -> KeyFLG) {
          //keyがマッチするものがあれば、そのポインタの配列を新しい配列に差し替え
          $this -> Original[$this -> pointer] = $this -> Updating;
        } else {
          //keyがマッチするものがなければ、末尾に追加
          $this -> Original[] = $this -> Updating;
        }
      }
    }
    return $this -> Original;
  }
}