こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

FlashとXMLとの連動

初心者ですがよろしくお願いします。
FlashとXMLとを連動させたフォトギャラリーを作成していますが
うまく読み込みできずnullになります。
Flash内の機能としては、
・自動スライド機能
・画像をクリックするとXML内のURLへジャンプ
を入れたいと思ってます。
下記内容を御覧頂きご指摘お願いします。
XML内
<Slides>
 <slide>
 <jpegURL>images/image1.jpg</jpegURL>
  <product_name>名前</product_name>
  <product_url>URL</product_url>
 </slide>
 <slide>
 <jpegURL>images/image2.jpg</jpegURL>
  <product_name>名前2</product_name>
  <product_url>URL2</product_url>
 </slide>
</Slides>

Flash内ActipnScript
slides_xml = new XML();
slides_xml.onLoad = startSlideShow;
slides_xml.load("slides.xml");
slides_xml.ignoreWhite = true;

//自動スライドを定義
function nextSlideload(){
nextSlideNode = currentSlideNode.nextSibling;
if (nextSlideNode == null) {
break;
} else {
currentIndex++;
updateSlide(nextSlideNode);
currentSlideNode = nextSlideNode;
}
}
// Show the first slide and intialize variables
function startSlideShow(success) {
if (success == true) {
rootNode = slides_xml.firstChild;
totalSlides = rootNode.childNodes.length;
firstSlideNode = rootNode.firstChild;
currentSlideNode = firstSlideNode;
currentIndex = 1;
updateSlide(firstSlideNode);
setInterval(nextSlideload,3500)
}
}
function nextSlideload(){
nextSlideNode = currentSlideNode.nextSibling;
if (nextSlideNode == null) {
break;
} else {
currentIndex++;
updateSlide(nextSlideNode);
currentSlideNode = nextSlideNode;
}
};
// Updates the current slide with new image and text
function updateSlide(newSlideNode) {
imagePath = newSlideNode.attributes.jpegURL;
slideText = newSlideNode.firstChild.nodeValue;
loadMovie(imagePath, targetClip);
}
// Event handler for 'Next slide' button
next_btn.onRelease = function() {
nextSlideNode = currentSlideNode.nextSibling;
if (nextSlideNode == null) {
break;
} else {
currentIndex++;
updateSlide(nextSlideNode);
currentSlideNode = nextSlideNode;
}
};
// Event handler for 'Previous slide' button
back_btn.onRelease = function() {
previousSlideNode = currentSlideNode.previousSibling;
if (previousSlideNode == null) {
break;
} else {
currentIndex--;
currentSlideNode = previousSlideNode;
updateSlide(previousSlideNode);
}
};

投稿日時 - 2008-01-11 18:00:36

QNo.3670486

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

DPE

XML の文字コードの問題・画像のパスの問題・ターゲットパスの誤りなど、外部ファイルが読み込めない理由にはいろいろな原因が考えられますが。
とりあえず、ファイルを読み込むこと自体には特に問題がないものとし、XML を解析する部分に限定します。


ざっと試してみただけなのですが、updateSlide 関数の中で画像のパスやテキストを取得する部分を

(↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)


 //<slide>ノード内の子ノードの値を取得
 imagePath = newSlideNode.childNodes[ 0 ].firstChild.nodeValue;
 slideText = newSlideNode.childNodes[ 1 ].firstChild.nodeValue;
 linkURL = newSlideNode.childNodes[ 2 ].firstChild.nodeValue;


このように書き換えてみてください。
変数 imagePath に画像のパス、slideText にテキスト、linkURL に URL が入ります。
trace アクションで各変数の中身を確認してみて、XML で指定した通りの値が表示されれば、XML の読み込みおよび解析して必要な情報を取り出す処理は成功していると言えます。

----------------------------------------------------------

ActionScript の XML オブジェクトの中には、解析した XML の情報そのものの他に、子の数・最初 / 次 / 最後の子といった、別のノードや関連するノードを参照するための手がかりもたくさん記録されます。

子のノードの情報は内部では配列変数で入っていますから、childNodes[ 0 ] というように配列変数で直接参照できますが、firstNode (最初の子ノード) や nextSibling (次の子ノード)といった相対的な表現で参照する方法もあります。
相対的な表現でノードを参照する場合は特に、どのノードを指しているのかをしっかり辿っていかないと、解析するノードを見失ってしまいます。


ご提示のスクリプトで、どの変数がどのノードを指しているのかを順番に辿りながら、画像を読み込む部分のスクリプトを解析してみましょう。

XML が読み込まれた時、startSlideShow 関数が呼び出されます。
この中で、各変数に次の通りのノードが設定されます。

 ・ rootNode
  slides_xml の firstChild (最初の子ノード)。
  つまり、取得した XML の最も外側のタグで囲まれている <Slides> ノードです。

 ・ firstSlideNode
  <Slides> には、<slide> ~ </slide> で囲まれた子ノードが2つあります。
  rootNode は <Slides> ノードで、これの最初の子ノード、つまり1番目の <slide> ノードのことです。

 ・ currentSlideNode
  startSlideShow 関数の中では、単に firstSlideNode の複製にすぎません。
  しかし、この変数の本来の役目は、各スライドに必要な情報をまとめている <slide> ノードを次々に参照していくことです。
  1枚目のスライドの情報があるノードを、との意味で初期値として firstSlideNode の値がコピーされていますが、
  スライドが進むと次の <slide> ノードを指すようになります。


nextSibling で自分と同じ階層に並んでいる次の子ノード、previousSibling で前の子ノードを参照できます。
変数 currentSlideNode は <slide> ノードの階層を指しており、ノードを移動するスクリプトでは <slide> と同じ並びのノードに移動します。
従って、currentSlideNode.nextSibling と currentSlideNode. previousSibling で、前後のスライドの情報( <slide> ノード)を取得できます。

<slide> ノードに更に子ノードが増えるなど <slide> ノードの下の階層の構成が変わったとしても、” <Slides> ノードの下に <slide> ノードがいくつか並んでいる”という関係さえ変わらなければ、currentSlideNode の nextSibling や previousSibling による <slide> ノード間の移動はそのまま利用できます。

前後のスライドに移動するボタンのスクリプトは検証しておりませんが、見たところ <slide> ノード単位で参照するノードを変化させるスクリプトと思われるので、今回は特に変更する必要はないかと思います。

*****************************

今回の肝は updateSlide 関数です。

updateSlide 関数は、1件の <slide> ノードの情報を受け取り、このノードを解析してスライドに必要な情報を取り出し、取り出した画像のパスから画像を読み込む関数と思われます。
ご提示のスクリプトですと、この関数の中では

 ・変数 imagePath に、引数で渡されてきたノードの持つ” jpegURL ”属性の値
 ・変数 slideText に、引数で渡されたノードの値

を格納するようになっています。
つまり、この関数の設計では、XML の記述が

 <Slides>
  <slide jpegURL="image1.jpg">名前1</slide>
  <slide jpegURL="image2.jpg">名前2</slide>
   :
 </Slides>

このような構成になっていないと、スライドに使う画像のパスとテキストを正確に取得できません。

画像のパスとテキスト・・・と2種類だけならこれでもいいのですが、今回はもう1つ、クリックした時に開く URL の情報を増やしたいのです。
<slide> ノードに更に子ノードを設けて分かりやすく記述できるのが、XML の特長です。
ただ、<slide> ノードに子ノードを増やすと、このスクリプトで想定している XML と構成が変わってしまいますから、このままでは使えません。
<slide> ノードまでの構成は変わらないので、変更する箇所は updateSlide 関数の中で <slide> ノードの子ノードを解析する部分、ということになります。


updateSlide 関数の解析部分を、ご質問文にある通りの

 <Slides>
  <slide>
   <jpegURL>image1.jpg</jpegURL>
   <product_name>名前1</product_name>
   <product_url>URL1</product_url>
  </slide>
  <slide>
   :
  </slide>
 </Slide>

という構成の XML を解析できるように変更してみましょう。

この XML では、各 <slide> ノードに3つの子ノードがあります。
imagePath 等の変数に値を格納する都合もあって、 nextSibling などの相対的な表現で子ノードを辿っていくよりも、配列変数で直接子ノードを参照した方が簡単だと思います。
各子ノードは、<jpegURL> = <slide> ノードの最初(0番目)の子( childNodes[ 0 ] )、<product_name> =1番目の子( childNodes[ 1 ] )、<product_url> =2番目の子 ( childNodes[ 2 ] ) で参照できます。

ActionScript の XML では、タグで囲まれている値も1つの子ノードとして考えます。
この例ですと、例えば <jpegURL> タグで囲まれている値を取得する時は” <jpegURL> ノードの最初の子”が持っている値( nodeValue )となります。
普通に考えると、<jpegURL> ノードの nodeValue が image1.jpg なのでは?という気がしますが、ActionScript では”ノードの最初の子”の nodeValue で取得しますので、ご注意ください。


updateSlide 関数では、<slide> ノードまでの参照が引数で渡されてくると想定されています。
<slide> ノードの下の階層の構成が、元のスクリプトで想定しているものと変わりましたが、<slide> ノードまでの関係は変わっていませんので、この引数はそのまま使用できます。

まとめますと、updateSlide 関数の中では、仮引数を利用して

 <jpegURL> の値 = newSlideNode.childNodes[ 0 ].firstChild.nodeValue;
 <product_name> の値 = newSlideNode.childNodes[ 1 ].firstChild.nodeValue;
 <product_url> の値 = newSlideNode.childNodes[ 2 ].firstChild.nodeValue;

で、<slide> ノードの3つの子ノードの値を取得することができます。

*****************************

XML は階層を自由に記述できる言語です。
しかし、それゆえに、階層の構成を変えた時には解析するスクリプトも合わせて変えなければならないという、厄介な面もあります。
XML を使うスクリプトは、後で子ノードを付け足したり削除するなど、XML で記述する階層の構成を変えてしまうと、役に立たなくなることがあります。

ちなみに、デバッガという機能を使うと、XML オブジェクトの内容をツリー形式で見ることができます。
機会がありましたら利用してみてください。

投稿日時 - 2008-01-12 22:09:35

お礼

ご指摘いただきありがとうございました。
アップデート時のスクリプトを変更したところ
XMLデータを読み込みできました。
ありがとうございました。

投稿日時 - 2008-01-15 11:52:50

ANo.1

ムービーの構造がどうなっているかわからないもののスクリプトを,
そんなにゴチャゴチャ書かれても,何がどうなっているのかわかりませんよ。

まず,XML ですが。
それは質問用に用意された XML ですか?
それとも元がそうなっているのですか?
インデントの全角空白文字や,変な所に入っている全角空白文字は全て削除してください。

---「slides.xml」-----------------------------
<Slides>
<slide>
<jpegURL>images/image1.jpg</jpegURL>
<product_name>名前</product_name>
<product_url>URL</product_url>
</slide>
<slide>
<jpegURL>images/image2.jpg</jpegURL>
<product_name>名前2</product_name>
<product_url>URL2</product_url>
</slide>
</Slides>
------------------------------------------

この 「slides.xml」 ですが,
文字コードを UTF-8 で保存していますか?
もししていなければ UTF-8 で保存してください。


次に ActionScript の方ですが,
もっとシンプルにしないとどこに問題があるかわからないでしょう。

あと,
ちゃんと読み込まれたかどうかとか,
変数の値はどうなっているかとかは,
trace();
で調べてみれば良いのですよ。
特に XML のノードや属性は掴みにくい物です。
XML の場合は trace(); を無茶苦茶に入れればなんとかなるものです。

Flash で新規ドキュメントを作成し,
XML が保存してあるフォルダに任意の名前で保存し,
フレーム1 に次のスクリプトをコピペして,
「制御」→「ムービープレビュー」してみてください。
うまくロードされれば色々見える物が見えてくると思います。

---------------------------------------------------
slides_xml = new XML();
slides_xml.onLoad = startSlideShow;
slides_xml.load("slides.xml");
slides_xml.ignoreWhite = true;

function startSlideShow(success) {
if (success == true) {
rootNode = slides_xml.firstChild;
totalSlides = rootNode.childNodes.length;
trace("totalSlides = "+totalSlides);
trace("------------------------------------");
firstSlideNode = rootNode.firstChild;
trace("firstSlideNode = "+firstSlideNode);
trace("------------------------------------");
trace(rootNode.childNodes[0].childNodes[0]);
trace("------------------------------------");
trace(rootNode.childNodes[0].childNodes[0].firstChild.nodeValue);
trace(rootNode.childNodes[0].childNodes[1].firstChild.nodeValue);
trace(rootNode.childNodes[0].childNodes[2].firstChild.nodeValue);
trace(rootNode.childNodes[1].childNodes[0].firstChild.nodeValue);
trace(rootNode.childNodes[1].childNodes[1].firstChild.nodeValue);
trace(rootNode.childNodes[1].childNodes[2].firstChild.nodeValue);
}
}
---------------------------------------------------

上のようにして得られたものを参考にして,
色々動作させながら作成していけばできるのではないでしょうか。

投稿日時 - 2008-01-12 14:10:37

お礼

初めて質問するもので迷ってしまいすべて書いてしまいました。
すいませんでした。ぜひ試してみます。
ありがとうございました。

投稿日時 - 2008-01-12 14:52:57

あなたにオススメの質問