Msxml2.DOMDocumentのdataType ってなによ?

.NET Frameworkの素敵機能をJScriptで使いたいのエントリで出てきた

var element = new ActiveXObject("Msxml2.DOMDocument").createElement("temp");
element.dataType = "bin.hex";

は何なのか。このコード自体は検索して出てきたのをパ○っただけなんだけど、分からないのは気持ち悪いのでちょっとやる気出して調べてみた。

dataTypeプロパティの現状

まずIXMLDOMDocument/DOMDocument MembersにMsxml2.DOMDocumentのプロパティ及びメソッド一覧があり、その中にdataTypeがある。さて中には何が書いてあるかというと、このdataTypeプロパティはXDR(XML Data Reduced) Schemaというルールで定義されているが、このルールはMsxml2.DOMDocument6.0ではすでに廃止されている。XDRというルール自体もXSD(XML Schema Definition)までの繋ぎでしかない。しかしそれでは不便と思ったのか6.0でも代替の実装で使えるようにしてる。という、なんだか一抹の不安を覚える現状が分かった所で具体的な話に入ろう。

dataTypeの取り得る値一覧

bin.base64 Base64エンコードされたバイト列。
bin.hex 16進数で表されたバイト列。
boolean 0もしくは1の値を取る。ただしここで0はfalse、1はtrue。
char char型。
date 日時、ただし時刻は含まない。
例:"1994-11-05"
dateTime 日時及び時刻、TIME ZONEの指定不可。
例:"1988-04-07T18:39:09"
dateTime.tz 日時及び時刻、TIME ZONEの指定可。
例: "1988-04-07T18:39:09-08:00"
entity エンティティ。
entities エンティティのリスト。
enumeration 属性値で使える文字列ルールの話。あんまり関係ない。
例: "Red Blue Green"
fixed.14.4 整数部分が14桁で少数部分が4桁以内の数値。
例: 9999.0044
float 実数。 (2.2250738585072014E-308-1.7976931348623157E+308).
例: 111, 3.14, -123.456E+10
i1 1バイトの符号付き整数(-128 - 127)
例: 1, 127, -128
i2 2バイトの符号付き整数(-32768 - 32767).
例: 1, 703, -32768
i4 4バイトの符号付き整数(-2147483648 - 2147483647).
例: 1, 703, -32768, 148343, -1000000000
i8 8バイトの符号付き整数(-9223372036854775808 - 9223372036854775807).
例: 1, 703, -32768, 1483433434334, -1000000000000000
id 通常言う所の一意のID。
例: Cust1
idref document内でIDを1つ参照する。
例: Cust1
idrefs document内でIDを複数参照する。
例: Cust1 Cust2 Cust3
int 符号付き整数。
例: 11123, -123
nmtoken 属性値で使える文字列ルールの話。あんまり関係ない。
例: Cust1
nmtokens 属性値で使える文字列ルールの話。あんまり関係ない。
例: Cust1 Cust2 Cust3
notation NOTATION型。
number 数値。(2.2250738585072014E-308 - 1.7976931348623157E+308).
例: 111, 3.14, -123.456E+10
r4 浮動小数点数。ただし4バイト。 (1.17549435E-38 - 3.40282347E+38).
r8, float 浮動小数点数。(2.2250738585072014E-308 - 1.7976931348623157E+308).
string 文字列。
例: "This is a string"
time 時刻、ただし日時は含まない。TIME ZONEの指定不可。
例: "08:15:27"
time.tz 時刻、ただし日時は含まない。TIME ZONEの指定可。
例: "08:15:27-05:00"
ui1 1バイトの符号無し整数(0-255)。
例: 1, 255
ui2 2バイトの符号無し整数(0-65535)。
例: 1, 255, 65535
ui4 4バイトの符号無し整数(0-4294967296)。
例: 1, 703, 3000000000
ui8 8バイトの符号無し整数(0-18446744073709551615)。
例: 1483433434334
uri URI
例: "urn:schemas-microsoft-com:Office9"
uuid UUID。16進数で表される一意の値。
例: 333C7BC4-460F-11D0-BC04-0080C7055A83

具体的な使い方

始めに断っておくが以下のコードはdataTypeのサンプルというだけであって殆ど役に立たない物ばかりなのでそのつもりで。Base64エンコードとかバイト列を16進数化辺りが使える程度。
ここで使用するのはdataType、nodeTypedValue、textの3つ。dataTypeは説明した。nodeTypedValueはdataTypeで指定したデータでtextは文字通り文字列。従ってnodeTypedValueは文字列とは限らない。現にbin.hexではバイト列を指定している。

//Base64でエンコード
var bytes = new ActiveXObject("System.Text.UTF8Encoding").GetBytes_4("0123456789abcdef");
var element = new ActiveXObject("Msxml2.DOMDocument").createElement("temp");
element.dataType = "bin.base64";
element.nodeTypedValue = bytes;
WScript.Echo(element.text);
//ユニコード変換
var element = new ActiveXObject("Msxml2.DOMDocument.6.0").createElement("hash");
element.dataType = "char";
element.text = "あ";
WScript.Echo(element.nodeTypedValue);

ただし渡すデータはchar型なので一文字ずつしか出来ない。あとnodeTypedValueで返ってくるのは10進数なので16進数にしないといけない。

//年号を取得
var element = new ActiveXObject("Msxml2.DOMDocument.6.0").createElement("temp");
element.dataType = "date";
element.text = "2016-06-29";
var date = element.nodeTypedValue;
var calendar = new ActiveXObject("System.Globalization.JapaneseCalendar");
WScript.Echo(calendar.GetEra(date));//4を返す。4は平成を表す。

dataTypeでdateを指定しているがここはdateTimeでも一緒。