InDesignのスクリプトで、たとえば「8ページにあるテキストフレーム内のXML要素にアクセスしたい」というとき、どうやって探せばいいのでしょうか。
XML構造を見ても、「その要素がどのページにあるか」はわかりません。
そういうときは、「8ページのテキストフレームにXMLタグがついているかどうか」または、「テキストフレーム内の文字がXMLタグ[ ]かどうか」というように、スクリプトでオブジェクトの属性を調べて判断します。
InDesignドキュメントのサンプル
次のような、InDesignのページ内にテキストフレームが2つあるドキュメントを用意しました。
赤色になっているのは、<著者紹介>のXMLタグのついたテキストフレーム。
さらに、その中の文字列「リプちん」には<著者>のXMLタグがついています。
その下にある「アプりん」の文字の入ったテキストフレームにはXMLタグはついていません。
実行するスクリプト
スクリプトでは、「associatedXMLElement(または、associatedXMLElements)」プロパティを使って、ページアイテムにXMLタグが付いているかどうかを調べます。
#target indesign
var objDoc = app.activeDocument;
var toString = Object.prototype.toString;
var objTextframe_riptin = objDoc.pages[0].textFrames[1];
var objTextframe_aprin = objDoc.pages[0].textFrames[0];
// 「リプちん」のテキストフレームの4文字目
var ret_riptin= toString.call(objTextframe_riptin.characters[3].associatedXMLElements);
// 「アプりん」のテキストフレームの1文字目
var ret_aprin= toString.call(objTextframe_aprin.characters[0].associatedXMLElements);
// 「リプちん」のテキストフレーム
var ret_txtfrm= toString.call(objTextframe_riptin.associatedXMLElement);
alert("「リプちん」のテキストフレームの4文字目 : " + ret_riptin + "\n\n" +
"「アプりん」のテキストフレームの1文字目 : " + ret_aprin + "\n\n" +
"「リプちん」のテキストフレーム : " + ret_txtfrm, "戻り値");
実行結果
オブジェクトの属性判定の結果を、alert()の文字列として表示しています。
オブジェクトがXMLタグだと認識した場合は、”[object XMLElement]”と表示されています。
サンプルの解説
スクリプトで、associatedXMLElement(s)プロパティを使う前に、ポイントが2つあります。
JavaScriptの Object.prototype.toString()
InDesignのページアイテムに対してassociatedXMLElement(s)プロパティを使うと、そのアイテムがXMLのアイテムであれば「XMLItem」が戻り値として返ります。
なので、その戻り値の型を調べれば良いのですが、JavaScriptのtypeof演算子の型判定では望むところの判定ができません。
そこで Object.prototype.toStringを使って、詳細な型を調べ、さらにそれをtoStringで文字列に変換して受け取ります。
サンプルスクリプトでは、4行目で次のように宣言しています。
var toString = Object.prototype.toString;
文字列のXMLタグを表している[ ]は、character
InDesignで文字列にXMLタグをつけると、その文字列が[ ]で囲まれます。
この[ ]は、ただの見た目ではなくて、実際にそこに[ ]というモノがあります。
試しに[ ]の前後をカーソルで移動すると、[ ]の前後にもカーソルが入ります。
[ ]が「ソコにいる」ので、コイツを「character」として捉えます。
なので「著者:リプちん」の「リ」の前の「コイツ」は、先頭から4つめの「character」というわけです。
サンプルの9・11行目では、テキストフレーム内の「character」を「toString」の引数として渡しています。
「リプちん」のテキストフレームの4文字目を評価
var ret_riptin= toString.call(objTextframe_riptin.characters[3].associatedXMLElements);
「アプりん」のテキストフレームの先頭文字を評価
var ret_aprin= toString.call(objTextframe_aprin.characters[0].associatedXMLElements);
実際のスクリプトでは、ページ上にある全てのテキストフレームをループで回しながら、さらにその中の文字列を1文字ずつループで回して判定していきます。
associatedXMLElements と associatedXMLElement
「associatedXMLElement」は、sがあったり、なかったり、ミスタイプしそうですが、
「character」など文字関連には、「associatedXMLElements」。
それ以外では、「associatedXMLElement」です。
戻り値は、文字列 “[object XMLElement]”
今回のサンプルスクリプトでは、最後にアラート表示で戻り値を表示しました。
実際にスクリプトを運用するときは、戻り値によってその後の処理をif文で分岐させます。
XML要素の内容や属性を修正する方法はこちら