ExtendscriptIndesignでXML要素を並べ替える

フラザリーニ

次の映画のリストを、の映画のversion==3D前に配置するように並べ替えたいと思いversion==2Dます。

入力

<films>
  <film name="Foobar" version="2D"></film>
  <film name="Foobar" version="3D"></film>
  <film name="Foobaz" version="2D"></film>
  <film name="Foobaz" version="3D"></film>
</films>

必要な出力

<films>
  <film name="Foobar" version="3D"></film>
  <film name="Foobar" version="2D"></film>
  <film name="Foobaz" version="3D"></film>
  <film name="Foobaz" version="2D"></film>
</films>

私はいじくり回して、次のコードに行き着きました。うまくいけば、それは理解できます。

/***
 Extend Array prototype to have a indeOf function
 ***/
Array.prototype.indexOf = function(item) { 
    var index = 0, length = this.length;  
    for ( ; index < length; index++ ) {
        if ( this[index] == item )  
            return index;  
        }  
    return -1;  
};  


var xmlString = '\
<films>\
    <film name="Foobar" version="2D"></film>\
    <film name="Foobar" version="3D"></film>\
    <film name="Foobaz" version="2D"></film>\
    <film name="Foobaz" version="3D"></film>\
</films>';

var xml = new XML(xmlString);
var sortVersion = ['2D', '3D'];
var uniqueMovies = new Array();


for (var index = 0; index < xml.elements().length(); index++) {
    if (index == 0) continue;

    // Fetch meta data of previous movie
    var prevTitle = xml.elements()[index - 1].@name;
    var prevVersion = xml.elements()[index - 1].@version;
    var prevVersionIdx = sortVersion.indexOf(prevVersion);

    // Fetch meta data of current movie
    var curTitle = xml.elements()[index].@name;
    var curVersion = xml.elements()[index].@version;
    var curVersionIdx = sortVersion.indexOf(curVersion);

    // If both movie title matches verify which movie should be prioritized
    if (prevTitle == curTitle) {
      if (prevVersionIdx < curVersionIdx) { 
          // Movie prio movie before less prio movie
          xml.insertChildBefore(xml.elements()[index - 1], xml.elements()[index]);
          // And delete the next in index
          delete xml.elements()[index + 1];
      }
    }   
}

$.writeln("-----");
$.writeln("");
$.writeln(xml.elements().toString());
return xml

ただし、このスクリプトを実行すると、次の結果が表示され、if条件が満たされ、要素onindex[1]が前に追加されても、何も変更されませんindex[0]

<films>
  <film name="Foobar" version="2D"/>
  <film name="Foobar" version="3D"/>
  <film name="Foobaz" version="2D"/>
  <film name="Foobaz" version="3D"/>
</films>

誰かが私がここで間違っていることを知っていますか?

RobC

代わりに、次のアプローチを検討してください。

script.jsx

/**
 * Extend Array prototype to have a indexOf function
 */
Array.prototype.indexOf = function(item) {
    var index = 0, length = this.length;
    for ( ; index < length; index++ ) {
        if ( this[index] == item )
            return index;
        }
    return -1;
};

var xmlString = '\
<films>\
  <film name="Foobar" version="2D"></film>\
  <film name="Foobar" version="3D"></film>\
  <film name="Foobaz" version="2D"></film>\
  <film name="Foobaz" version="3D"></film>\
  <film name="Foo" version="3D"></film>\
  <film name="Quux" version="2D"></film>\
  <film name="Quux" version="3D"></film>\
</films>';

var xml = new XML(xmlString);
var sortVersion = ['2D', '3D'];

// 1. Create a temporary XML object with a  matching `films` root element.
var tempXml = new XML('<' + xml.name() + '></' + xml.name() + '>');

for (var index = 0, max = xml.elements().length(); index < max; index++) {

  // Fetch meta data of previous movie
  var prevTitle = String(xml.elements()[index - 1].@name);
  var prevVersion = xml.elements()[index - 1].@version;
  var prevVersionIdx = sortVersion.indexOf(prevVersion);

  // Fetch meta data of current movie
  var curTitle = String(xml.elements()[index].@name);
  var curVersion = xml.elements()[index].@version;
  var curVersionIdx = sortVersion.indexOf(curVersion);

  // 2. Insert each XML element node from the original XML Object into
  // the temporary XML Object and position (i.e. sort) as neccessary.
  if (prevTitle === curTitle && prevVersion < curVersion) {
    tempXml.insertChildBefore(tempXml.elements()[index -1], xml.elements()[index])
  } else {
    // There's nothing to change (i.e. sort) so insert it as-is .
    tempXml.insertChildBefore(tempXml.elements()[index], xml.elements()[index])
  }
}

// 3. Overwrite original XML object's children with temporary (sorted) XML objects children.
xml.setChildren(tempXml.children());

// 4. Delete temporary XML object.
tempXml = undefined;


// Testing...
$.writeln(xml)
$.writeln('-----------------')
$.writeln(xml.elements().length())
$.writeln('-----------------')

説明:

元のXMLオブジェクトを操作(つまり並べ替え)しようとする代わりに、上記の要点は代わりに次のことを行います。

  1. <films>ルート要素のみを含む別のXMLオブジェクトを作成しますこのXMLオブジェクトは一時的なものになります。

  2. forループの各ターン中に、私たちは;

    • 元のXMLオブジェクトから一時XMLオブジェクトに各XML要素ノードのクローンを挿入します。
    • 必要に応じて、各XML要素ノードを配置(つまり並べ替え)します。
  3. 元のXMLオブジェクトの子要素ノードを一時的/ソートされたXMLオブジェクトの子要素ノードで上書きします。

  4. 最後に、一時的なXMLオブジェクトを削除します(つまり、に設定しますundefined)。これは不要になったためです。


結果

上記の要点の例には、次のソースXMLが含まれています。

<films>
  <film name="Foobar" version="2D"></film>
  <film name="Foobar" version="3D"></film>
  <film name="Foobaz" version="2D"></film>
  <film name="Foobaz" version="3D"></film>
  <film name="Foo" version="3D"></film>
  <film name="Quux" version="2D"></film>
  <film name="Quux" version="3D"></film>
</films>

これは次のように変換されます。

<films>
  <film name="Foobar" version="3D"/>
  <film name="Foobar" version="2D"/>
  <film name="Foobaz" version="3D"/>
  <film name="Foobaz" version="2D"/>
  <film name="Foo" version="3D"/>
  <film name="Quux" version="3D"/>
  <film name="Quux" version="2D"/>
</films>

注:質問で提供された例よりも複雑なXML構造と変換要件については、代わりにXSLT利用することを検討します現在の要件を考えると、このようなテンプレートで目的の結果が得られます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

TOP 一覧

  1. 1

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  2. 2

    Railsで宝石のレイアウトを使用するにはどうすればよいですか?

  3. 3

    Chromeウェブアプリのウェブビューの高さの問題

  4. 4

    Ansibleで複数行のシェルスクリプトを実行する方法

  5. 5

    アンドロイド9 - キーストア例外android.os.ServiceSpecificException

  6. 6

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  7. 7

    CSSのみを使用して三角形のアニメーションを作成する方法

  8. 8

    Google Playストア:アプリページにリーダーボードと実績のアイコン/バッジが表示されない

  9. 9

    GoDaddyでのCKEditorとKCfinderの画像プレビュー

  10. 10

    PyCharmリモートインタープリターはプロジェクトタブにサイトパッケージのコンテンツを表示しません

  11. 11

    Windows 7では、一部のプログラムは「ビジュアルテーマを無効にする」レジストリ設定を行いませんか?

  12. 12

    Get-ADGroupMember:このリクエストのサイズ制限を超えました

  13. 13

    Pyusb can't find a device while libusb can

  14. 14

    MySQLでJSON_LENGTHとJSON_EXTRACTを組み合わせる方法は?

  15. 15

    Postmanを使用してファイル付きの(ネストされた)jsonオブジェクトを送信する

  16. 16

    Swiftのブロックのパラメーターに関するドキュメントのマークアップ形式は何ですか?

  17. 17

    Reactでclsxを使用する方法

  18. 18

    追加後、ブートストラップマルチセレクトがテーブルで機能しない

  19. 19

    MongoDB Compass: How to select Distinct Values of a Field

  20. 20

    「埋め込みブラウザのOAuthログイン」を有効にしてコールバックURLを指定した後でも、Facebookのコールバックエラーが発生する

  21. 21

    複数行ヘッダーのJTableヘッダーテキストの折り返し(カスタムTableCellRenderer)

ホットタグ

アーカイブ