2

ご協力いただきありがとうございます。

私は Javascript にはかなり慣れていませんが、Java のバックグラウンドがかなり強いので、現在取り組んでいるこのプロジェクトで試してみようと思いました。

基本的に、私がやろうとしているのは、xml ファイルからデータを読み取り、作成中のページの html コードを作成することです。ここにあるw3schools のスクリプトを使用しました。私はそれを変更し、自分の xml からデータを取得し、必要な html コードのより基本的な生成を行うようにしました。

すべてのテスト/構築に使用しているページは次のとおりです。

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>xml test table</title>
<script>
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.open("GET","SWPlanetData.xml",false);
    xmlhttp.send();
    swDoc=xmlhttp.responseXML;
    var s=swDoc.getElementsByTagName("planet");
</script>
</head>
<body>
<div class="planets-info-container"> 
    <script>
            for (i=0;i<s.length;i++)
            {
                var plName
                    = s[i].getElementsByTagName("planetName")[0].childNodes[0].nodeValue;
            var plDesc
                = s[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;
            var plUrl
                = s[i].getElementsByTagName("linkUrl")[0].childNodes[0].nodeValue;
            var plUrlTxt
                = s[i].getElementsByTagName("linkText")[0].childNodes[0].nodeValue;
            var plShowsList
                = s[i].getElementsByTagName("show");
            var plGamesList 
                = s[i].getElementsByTagName("videoGame");

            // test section
            var test = ''
            test += '<div><table border = "1">\n' +
                '<tr><td>' + s[i].getElementsByTagName("showText")[0].childNodes[0].nodeValue
                + '</td><td>' + s[i].getElementsByTagName("showUrl")[0].childNodes[0].nodeValue  + '</td></tr>' 
                + '<tr><td>' + s[i].getElementsByTagName("gameText")[0].childNodes[0].nodeValue + '</td><td>'
                +   s[i].getElementsByTagName("gameUrl")[0].childNodes[0].nodeValue + '</td></tr>'
                + '</tr></table></div>'                 
                document.write(test);
                document.close();
            // end section

            document.write("<div class=\"planet-info-container\" id=\""+plName+"-container\">");
                document.write("<div class=\"name-row\"><div class=\"planet-name\">"+plName+"</div></div>");
                document.write("<div class=\"desc-row\">");
                    document.write("<div class=\"planet-desc\">"+plDesc+"</div>");
                document.write("</div>");
                document.write("<div class=\"appearances-row\"><ol class=\"shows\"><li>shows list</li>");
                for(j=0;j<plShows.length;j++){
                    document.write("nested for");
                    var showUrl = s[i].getElementsByTagName("showUrl")[j].childNodes[0].nodeValue;
                    var showText = s[i].getElementByTagName("showText")[j].childNodes[0].nodeValue;
                    document.write("<li><a href=\""+showUrl+"\">"+showText+"</a></li>");
                }
                document.write("</ol><ol class=\"games\"> games list");
                for(j=0;j<s[i].getElementByTagName("videoGame").length;j++){
                    var gameUrl = s[i].getElementsByTagName("gameUrl")[j].childNodes[0].nodeValue;
                    var gameText = s[i].getElementByTagName("gameText")[j].childNodes[0].nodeValue;
                    document.write("<li><a href=\""+gameUrl+"\">"+gameText+"</a></li>");
                }
                document.write("</ol></div>");
                document.write("<div class=\"locs-row\">");
                document.write("</div>");
                document.write("<div class=\"races-row\">");
                document.write("</div>");
                document.write("<div class=\"chars-row\">");
                document.write("</div>");
                document.write("<div class=\"links-row\">");
                    document.write("<div class=\""+plName+"-link\"><a href=\""+plUrl+"\">"+plUrlTxt+"</a></div>");
                document.write("</div>");
                document.write("</div><br />");
            }
        </script> 
</div>
</body>

コードは最後の入れ子になった for ループで壊れます。ここで document.write が終了し、「shows list」がページに出力されますが、内部の document.write には到達しません。

役立つ場合、xml には次のように編成されたスター ウォーズ ユニバースの惑星のリストが含まれています。

<planets>
<planet>
    <planetName>planet</planetName>
    <description>some text</description>
    <appearances>
        <show>
            <showUrl>url</showUrl>
            <showText>hyperlink text</showText>
        </show>
        <videoGame>
            <gameUrl>url</gameUrl>
            <gameText>hyperlink text</gameText>
        </videoGame>
    </appearances>
    <locationsOfInterest>
        <location>location name</location>
    </locationsOfInterest>
    <famousCharactersRelatedTo>
        <character>a character</character>
    </famousCharactersRelatedTo>
    <externalLinks>
        <link>
            <linkUrl>url</linkUrl>
            <linkText>hyperlink text</linkText>
        </link>
    </externalLinks>
</planet>

編集: 混乱を減らすためにコードを削減しようとすることで、これを必要以上に難しくしましたが、いくつかの重要なことを省略したり、入力したものの順序を間違えたりしたため、以前に持っていたコードをページ全体に置き換えました-は。

再編集: ある程度の進歩はありましたが、ネストされたループにまだ問題があります。最初のものに入りますが、2番目の変数を設定して最初の反復を完了する前に中断します。

var showText = s[i].getElementsByTagName("showText")[j].childNodes[0].nodeValue;

なぜこれが壊れるのか誰にもわかりますか?

4

3 に答える 3

2

あなたのコードで:

> var s = swDoc.getElementsByTagName("planet");

swDocが XML ドキュメントへの参照であることを願っています。

> var plShowsArr = s[i].getElementsByTagName("show");

が宣言または初期化されている場所を示していないiため、ここでエラーが発生すると予想されます。また、名前plShowsArrから配列だと思われるかもしれませんが、そうではありません。getElementsByTagNameはNodeListを返します。これは、長さの自己調整プロパティがあり、インデックスによってメンバーにアクセスできるという点で配列に似ています。しかし、類似点はここまでです。

> document.write("<div><table border = \"1\">");

一重引用符と二重引用符をネストして、引用を避けることができます。

  document.write('<div><table border="1">');

しかし、document.writeこの方法を使用することは最適とは言えません。ドキュメントの読み込みが完了した場合、 を呼び出すとdocument.write、新しいコンテンツを書き込む前に、まずドキュメント全体がクリアされます。document.writeいずれにせよ、マークアップの単一の文字列を作成し、 (適切な場合) マークアップを使用するか、コンテナー要素の innerHTML として設定する方がはるかに効率的です。

だからあなたはするかもしれません:

var markup = ''
...
  markup += '<div><table border="1">';

...
// If writing to a child window
document.write(markup);
document.close();

// If assigning to the innerHTML of a container element
var container = document.getElementById('containerID');
if (container) {
  container.innerHTML = markup;
}

後で次のようになります。

> document.write('<div class="appearances-row"><ol class="shows">shows list');

これにより、テキスト ノードが OL 要素の子として挿入されます。それは許可されていません。次に何が起こるかは実装に依存します。あなたの推測は私のものと同じくらい良いです。ユーザー エージェントを未解決のままにしました。

それで:

>  for(j=0;j<plShows.length;j++){

別の宣言されていない変数: jは、この行が実行されるとグローバル変数になります。

カウンターが何をしているかはまだ分析していません。それはあなたにお任せします。

編集

デバッガーを使用すると (Firefox の Firebug で実行できます)、次のようになります。

  1. XML に惑星の終了タグがありません

  2. document.closeドキュメントへの書き込みがすべて終了するまで使用しないでくださいdocument.write。ドキュメントの読み込み中に使用する必要はなく、スクリプトの後にさらに読み込む必要があります。

  3. の行for (j=0; j<plshows.length; j++){で、変数plshowsが定義されていないため、次のように置き換えますplShowsList

  4. document.write("</ol><ol class=\"games\"> games list");では、OL の後、テキストの前に LI を挿入する必要があります。

  5. の行var showText = s[i].getElementByTagName...では、参照にs[i]はメソッドがありませんgetElementByTagName。メソッドはgetElementsByTagName(このエラーが 2 行あります — コピー ペースト?)

コードに空白を少し追加すると、非常に読みにくくなります。そして、これらすべての document.writes を連結された文字列に変更し、div の innerHTML として 1 回挿入します (スクリプトを div の直後に移動します)。

上記のすべてを修正すると、「動作」します。請求書は郵送で...

于 2012-09-17T03:57:15.003 に答える
1

少なくとも 2 つの変更が必要だと思います。

次の 2 行を移動します。

var plShowsArr = s[i].getElementsByTagName("show");
var plGamesArr = s[i].getElementsByTagName("videoGame");

...外側のループの内側へ。どちらの行も、変数forによってインデックス付けされた現在の「planet」要素の子にアクセスしようとしています。i

for現時点では を使用しているが、使用plShows.lengthする必要がある内部ステートメントを更新しplShowsArr.lengthます。

必要に応じて、現在の「惑星」内から選択するのではなく、現在の「ショー」内から「showUrl」と「showText」を選択することで、内側のループを改善できます。

       for(j=0;j<plShowsArr.length;j++){
            document.write("nested for");
            var showUrl = plShowsArr[j].getElementsByTagName("showUrl")[0].childNodes[0].nodeValue;
            var showText = plShowsArr[j].getElementByTagName("showText")[0].childNodes[0].nodeValue;
            document.write("<li><a href=\""+showUrl+"\">"+showText+"</a></li>");
        }

他にも多くの改善を行うことができますが、それらは (おそらく?) 現在の問題とは直接関係ありません。

于 2012-09-17T04:01:03.560 に答える
0

ご参考までに、これは私の側ではばかげたことでした。の大きな違い

var showUrl = plShowsArr[j].getElementsByTagName("showUrl")[0].childNodes[0].nodeValue;

var showText = plShowsArr[j].getElementByTagName("showText")[0].childNodes[0].nodeValue;

ここにあります:

n00bのようなコードになる方法...

于 2012-09-17T15:35:00.933 に答える