私的メモ!Adobeのjavascript(ESTK)でのXMLデータをゴニョゴニョとするjsxのコードをいろいろとメモ

どうも、東京は池袋で開催されていたpage2019から帰って来たshock tmです。1日中歩いてたので、背中バキバキでした。
それにしてもindesign server のブースで貰った布袋がいい感じです。一番普段遣い出来そうだし。


そんなわけで(どんなわけだ!)、今回はAdobeのjavascript(ESTK)でのXML操作のソースコードです。

結構XMLとか好きで、いろいろ属性とか書き方もあって便利ですよね。前にもこういう記事書いたことあるし(そんなセッションな…)。

しかしながら私自身が【.net】(Linq)や【jQuery】とかイロイロな言語を使うので記述方式を忘れがちなんですよ。なのでESTKの分はここでまとめちゃいます。

目次

先ずは目次です。自分で見やすいようにしないとね。

    1. XML読み込み
    2. 要素や属性値の取り出し
      • 要素内容を決め打ちで取り出し
      • 要素内容を変数で取り出し
      • 属性値を決め打ちで取り出し
      • 属性値を変数で取り出し
    1. 要素の操作
      • 要素内容の変更
      • 要素内容の削除
      • 要素内容の追加
    1. ループカウンタで処理
    2. 属性値指定での取り出し
      (if文なんてそんなセッションな!【第2章】)

      • 等価式やなんやら
      • 正規表現で指定
    1. その他の要素の取得方法
      • chiledrenとelements
      • リアルな使い方

使用するサンプル

とりあえず使用するサンプルのxmlはこんな感じです。

サンプルxml
<xml>
	<superman 属性="正義超人" position="リーダー">
		<name>ロビンマスク</name>
	</superman>
	<superman 属性="正義超人" position="大王">
		<name>キン肉マン</name>
	</superman>
	<superman 属性="悪魔超人" position="悪魔六騎士">
		<name>アシュラマン</name>
	</superman>
	<superman 属性="完璧超人" position="首領">
		<name>ネプチューンマン</name>
	</superman>
	<superman 属性="悪魔超人" position="七人の悪魔超人">
		<name>バッファローマン</name>
	</superman>
	<human 属性="正義超人" position="アパッチ">
		<name>ジェロニモ</name>
	</human>
</xml>

例によって超人データです。最近は要素内要素より属性値に記述する方が便利だと個人的には思うわけですよ。でもまぁサンプルなので要素内要素もあります。ちなみに人間状態のジェロニモもいますがあとで出てきますので、、、。

XML読み込み

まずは何はともあれ読み込みです。こういうものは使いやすいように関数にします。

var XElement=ReadXML("C:/サンプルxml.xml")
function ReadXML(path){
	var openFile=new File(path);//ファイルオブジェクトを作成
	openFile.encoding="UTF8";//エンコーディングをUTF-8にする
	openFile.open("r");//ファイルを開く
	var src=openFile.read();//文字列を読み込む
	return(new XML(src));//文字列をXMLにパースして返す
}

とまぁこんな感じです、変数XElementに代入しています、フツーですね。ポイントは文字コードをUTF-8に指定するところでしょうか?指定しないと、正しく読み込めなかったことがありましたので指定するようにしてます。

要素や属性の取り出し

要素内容を決め打ちで取り出し

まずは要素名が分かっているときは直接指定できます。[0] で1つ目を指定しています。

var XElement=ReadXML("C:/サンプルxml.xml")
alert(XElement.superman[0].name)
結果:ロビンマスク

要素内容を変数で取り出し

変数で指定する場合は[ ]で囲んで指定します。[2] で3つ目を指定しています。

var XElement=ReadXML("C:/サンプルxml.xml")
var mans="superman"
alert(XElement[mans][2].name)
結果:アシュラマン

属性値を決め打ちで取り出し

まずは属性名が分かっているときは【.@】の後に【属性名】で直接指定できます。[0] で1つ目を指定しています。

var XElement=ReadXML("C:/サンプルxml.xml")
alert(XElement.superman[0].@属性)
結果:正義超人

属性値を変数で取り出し

変数で指定する場合は【attribute( )】で囲んで指定します。[2] で3つ目を指定しています。

var XElement=ReadXML("C:/サンプルxml.xml")
var mans="superman",type="position"
alert(XElement[mans][2].attribute(type))
結果:悪魔六騎士

ちなみに【attribute】ではなく【attributes】にすると指定関係なく全部行っちゃいます。

var XElement=ReadXML("C:/サンプルxml.xml")
var mans="superman",type="position"
alert(XElement[mans][2].attributes(type))
結果:悪魔超人悪魔六騎士

要素の操作

要素内容の変更

要素内容の変更はそのままです(nameタグを変更)。

var XElement=ReadXML("C:/サンプルxml.xml")
XElement.superman[0].name="ウォーズマン"
結果 : ウォーズマン

要素内容の削除

要素内容の削除は頭に【delete】を使用します(nameタグを削除)。

var XElement=ReadXML("C:/サンプルxml.xml")
delete XElement.superman[0].name
結果 : true

属性の削除も同じ使い方です。

var XElement=ReadXML("C:/サンプルxml.xml")
delete XElement.superman[0].@属性
結果 : true

要素内容の追加

要素内容の追加は【+】を使用します

var XElement=ReadXML("C:/サンプルxml.xml")
var newSuperMan=new XML("<superman 属性='完璧超人' position='完璧無量大数軍'><name>ネメシス</name></superman>")
XElement.superman+=newSuperMan

ちなみに公式の【javascript_tools_guide】には追加するときは関数が便利だよ!書いてありますので(多分…)、超人用に作ってみました。

function makeXML(name,attribute,position){
	return <superman 属性={attribute} position={position}><name>{name}</name></superman>;
}
XElement.superman+=makeXML("ネメシス","完璧超人","完璧無量大数軍")

{ }ってこういう風にも使えるのか…

ループカウンタで処理

for文で回して処理。

var XElement=ReadXML("C:/サンプルxml.xml")
	for(var i=0;i<XElement.superman.length();i++){
	alert(XElement.superman[i].name)
}
結果:ロビンマスク
キン肉マン
アシュラマン
ネプチューンマン
バッファローマン

属性値指定での取り出し

さて、【属性値指定での取り出し】ESTK用にもあります!なかったらセッションだぜ?

var XElement=ReadXML("C:/サンプルxml.xml")
var supermans=XElement.superman.(@属性=="悪魔超人")
for(var i=0;i<supermans.length();i++){
	alert(supermans[i]["name"])
}
結果 : アシュラマン
バッファローマン

その他、例えば否定式を使ったり、

var XElement=ReadXML("C:/サンプルxml.xml")
var supermans=XElement["superman"].(@属性!="悪魔超人")
for(var i=0;i<supermans.length();i++){
	alert(supermans[i]["name"])
}
結果 : ロビンマスク
キン肉マン
ネプチューンマン

はたまた正規表現を使ったりもできます。

var XElement=ReadXML("C:/サンプルxml.xml")
var supermans=XElement["superman"].(@属性.match(new RegExp("正義","g")))
for(var i=0;i<supermans.length();i++){
	alert(supermans[i]["name"])
}
結果 : ロビンマスク
キン肉マン

複数指定はこういう感じかなぁ?(意地でもif文は使いたくない模様)

var XElement=ReadXML("C:/サンプルxml.xml")
var supermans=XElement.superman.(@属性=="正義超人").(@position=="大王")
for(var i=0;i<supermans.length();i++){
	alert(supermans[i]["name"])
}
結果 : キン肉マン

要素を全取得する場合

chiledrenとelements

んで、やっとジェロニモの出番なんですが、例えばサンプルxmlの数を数えるとしましょう。

var XElement=ReadXML("C:/サンプルxml.xml")
XElement.superman.length()
結果 : 5

これまでは要素【superman】を取得してきたので、5つしかありません。しかし【human】のジェロニモも加えると6つになるはずです。その場合は例えば、

//children()を使用
var XElement=ReadXML("C:/サンプルxml.xml")
XElement.children().length()
結果 : 6
//elements()を使用
var XElement=ReadXML("C:/サンプルxml.xml")
XElement.elements().length()
結果 : 6

上記を使用します。サンプルの場合は結果は同じですが、役割は違います。それは下記のような裸の文字列(サンプルは【飛翔の神】)が入ってる場合などです。

サンプルxml2
<xml>
	<superman 属性="正義超人" position="リーダー">
		<name>ロビンマスク</name>
	</superman>
	<superman 属性="正義超人" position="大王">
		<name>キン肉マン</name>
	</superman>
	<superman 属性="悪魔超人" position="悪魔六騎士">
		<name>アシュラマン</name>
	</superman>
	<superman 属性="完璧超人" position="首領">
		<name>ネプチューンマン</name>
	</superman>
	<superman 属性="悪魔超人" position="七人の悪魔超人">
		<name>バッファローマン</name>
	</superman>
	<human 属性="正義超人" position="アパッチ">
		<name>ジェロニモ</name>
	</human>
	飛翔の神
</xml>
//children()を使用
var XElement=ReadXML("C:/サンプルxml2.xml")
XElement.children().length()
結果 : 7
//elements()を使用
var XElement=ReadXML("C:/サンプルxml2.xml")
XElement.elements().length()
結果 : 6

1と2と結果が分かれました。要素でなくても拾ってしまうということかな?

リアルな使い方

んで、リアルな使い方は

var XElement=ReadXML("C:/サンプルxml2.xml")
var mans=XElement.children().(@属性=="正義超人")
for(var i=0;i<mans.length();i++){
	alert(mans[i]["name"])
}
エラー:@属性 は未定義です。

と【children()】だとエラーが吐かれます。生の文字の【飛翔】も要素タグとして処理しようするからですね。

var XElement=ReadXML("C:/サンプルxml2.xml")
var mans=XElement.elements().(@属性=="正義超人")
for(var i=0;i<mans.length();i++){
	alert(mans[i]["name"])
}
結果:ロビンマスク
キン肉マン
ジェロニモ

【elements()】だと要素でないものは排除してくれるみたいで、大丈夫です。ちなみに下記のような場合もエラーが出ます。

エラーxml1
<xml>
	<superman 属性="正義超人" position="リーダー">
		<name>ロビンマスク</name>
	</superman>

</xml>

空改行なら大丈夫ですが、全角スペースなどが入るとダメです、これで3時間悩んだことがあります。あと、

エラーxml2
<xml>
	<superman 属性="正義超人" position="リーダー">
		<name>ロビンマスク</name>
	</superman>
	<superman 属性="正義超人">
		<name>キン肉マン</name>
	</superman>
</xml>

上記のように属性値がない要素が混じってる場合も(ex キン肉マンに【@position】が無い)。

XElement=ReadXML("C:/error2.xml")
var mans=XElement.elements().(@position!="")
for(var i=0;i<mans.length();i++){
	alert(mans[i]["name"])
}
エラー:@position は未定義です。

となってしまいますので、要注意です。

まとめ

とまぁ、こんな感じででしょうか? 意外と便利なコマンドも多数(と思う…)。何か間違いがあればお知らせいただくと幸いです。

スポンサーリンク

スポンサーリンク

私的メモ!Adobeのjavascript(ESTK)でのXMLデータをゴニョゴニョとするjsxのコードをいろいろとメモ」への2件のフィードバック

  1. この裸状態の「飛翔の神」を取り出すにはどう指定すればいいんですか?

    1. リアルな使い方としては、
      超人の神だからって特別扱いせずに

      <SupermanGod 属性="超人の神" position="邪悪の神" 備考="1億パワー">
           <name>飛翔の神</name>
      </SupermanGod>

      とちゃんと要素タグに入れてやることです。

      どうしても取り出しを希望なら
      【children()】から【localName()】を【null】に
      指定すればOKですね。

      var XElement=ReadXML("C:/サンプルxml.xml");
      var mans=XElement.children().(localName()==null);
      for(var i=0;i<mans.length();i++){
          $.writeln(mans[i]);
      }

      【children()】後の検索って色々指定できますなぁ。
      いつ使うかわからんけど。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です