InDesign スクリプト テーブルをXMLに変換

テーブルをXMLに変換するスクリプトは、これで良いのかな・・・？

~~~JavaScript
/*
更新 2021/06/15
*/

// アプリ指定
#target "indesign";

// スクリプト名
var scriptName = "テーブルをXMLに変換";

//スクリプトの動作指定（一つのアンドゥ履歴にする、及び、アンドゥ名）
app.doScript(function () {

    // XMLのエンコーディング
    var encoding = "Shift_JIS"

    // ダイアログ
    var dialogueFlg = confirm("選択したテキストフレームにある最初のテーブルをXMLに変換します。"
    + "\r\r" + "ヘッダー（最上段の行）は変換されません。"
    + "\r\r" + "要素名の最初には数字（0～9）や空白等が使えませんので注意して下さい。"
    + "\r\r" + "テーブルの例"
    + "\r" + "要素名" + "\t" + "要素の内容" + "\t" + "属性1" + "\t" + "属性1の内容" + "・・・等々","", scriptName);

    // Noの場合
    if (dialogueFlg == false) {

        // 終了
        exit();
    }

    // タグ名のプレフィックスを入力
    var tagNamePrefix = prompt("要素名のプレフィックスが必要な場合は入力して下さい。","",scriptName);

    // キャンセルされた時の処理
    if(tagNamePrefix == null){

        // スクリプトを終了
        exit();
    }

    // 対象のストーリー
    var targetStory;

    // 成型されたXML
    var moldXML　= "<?xml version='1.0' encoding='" + encoding + "' standalone='yes'?>" + "\r" + "<Root>";

    // 選択がある場合
    if(app.activeDocument.selection.length > 0){

        // 選択オブジェクトのストーリーを入れる
        targetStory = getStory(app.activeDocument.selection[0]);

        // テーブルがある場合
        if(targetStory.tables.length > 0){

            // ヘッダーを除いた行の数だけ繰り返す
            for(var i = 1; i < targetStory.tables[0].rows.length; i++){

                // 行にセルが２つ以上ある場合
                if(targetStory.tables[0].rows[i].cells.length >= 2){

                    // セルが空ではない場合
                    if(targetStory.tables[0].rows[i].cells[0].contents != ""){

                        // XML成型
                        moldXML += "\r" + "<" + tagNamePrefix + targetStory.tables[0].rows[i].cells[0].contents;

                        // 三っ目のセルから初めて一つ飛ばしてセルの数だけ繰り返す
                        for(var ii = 2; ii < targetStory.tables[0].rows[i].cells.length; ii += 2){

                            // セルに内容がない場合
                            if(targetStory.tables[0].rows[i].cells[ii].contents != ""){

                                // 次のセルが存在する場合
                                if(ii + 1 < targetStory.tables[0].rows[i].cells.length){

                                    // XML成型
                                    moldXML += " " + targetStory.tables[0].rows[i].cells[ii].contents + "='" + targetStory.tables[0].rows[i].cells[ii+1].contents + "'";
                                }
                            }
                        }

                        // XML成型
                        moldXML += ">"  + targetStory.tables[0].rows[i].cells[1].contents + "</" + tagNamePrefix + targetStory.tables[0].rows[i].cells[0].contents + ">"
                    }
                }
            }
        }

        // 文字を追加
        moldXML += "\r" + "</Root>";

        // ダイアログX座標
        var dialogWidthXCoordinates = 0;

        // ダイアログY座標 
        var dialogWidthYCoordinates = 0;

        // ダイアログ幅
        var dialogWidth = (app.activeDocument.layoutWindows[0].bounds[3] - app.activeDocument.layoutWindows[0].bounds[1]) / 2

        // ダイアログ高さ
        var dialogHeight = (app.activeDocument.layoutWindows[0].bounds[2] - app.activeDocument.layoutWindows[0].bounds[0]) / 2

        // 段落スタイル選択用ダイアログ作成
        var textWindow = new Window("dialog", scriptName, [dialogWidthXCoordinates, dialogWidthYCoordinates, dialogWidthXCoordinates + dialogWidth, dialogWidthYCoordinates + dialogHeight]);

        // エディットテキスト追加
        textWindow.add("edittext",[ 20, 20, dialogWidth - 20, dialogHeight - 20],moldXML,{readonly:true,multiline:true});

        // 中央に
        textWindow.center();

        // 表示
        textWindow.show();
    }


//スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);

/* ストーリーを取得する関数、引数（オブジェクト）の宣言 */
function getStory(anyObject) {

    // parentStoryプロパティが存在する場合
    if (anyObject.hasOwnProperty("parentStory") == true) {

        // エラー処理
        try{

            // parentStoryの値がある場合
            if (anyObject.parentStory) {

                // コンストラクタ名を戻す
                return anyObject.parentStory;
            }

        // エラーの場合
        }catch(e){

            // 抜ける
            return;
        }

    // Applicationの場合
    } else if (anyObject.constructor.name == "Application") {

        // 抜ける
        return;
    }

    // オブジェクトの階層を一つ上げて再帰関数
    return getStoryConstructorName(anyObject.parent);
}
/* ストーリーを取得する関数の宣言終了 */
~~~