2011-12-08 2 views
0

XMLファイルがPHPでエコーされていて、すべてのコードがうまく動作しますが、問題はタグ内にあります(検査と属性は何のエコーであるのか)複数のタグ(例、つまり、受験番号としてエコーされているものだ)と私は、テーブルにデータをエコーし​​ていると私はそれがこのようにそれを表示したい:PHP、XML、エコー時に繰り返し属性の問題


|第1章|第2章|

| - 試験1 --- |試験1 --- |

| - 試験2 --- |試験2 --- |

|第3章|第4章|

| - 試験1 --- |試験1 --- |


しかし、私は何を取得していますがこのようなものである:(私はなぜ知っているけれども)


|第1章|

| - 試験1 --- |

|第1章|

| - 実験2 --- |

|第2章|

| - 試験1 --- |


私はテーブルデータ内の変数として持っているタグの属性をエコーし​​ていますので、それはタグの属性を繰り返し続けていると私は理由を知っています。だから問題はなぜ起こっているのではなく、私が望むようにそれを表示するためにどのように変更できるのでしょうか。私は推測

は多分つ以上があるかどう属性を削除する方法があります(私はあなたがそれを削除することができます知っているが、私は一度それを表示する方法を知っていると他の人を削除しないでください)

コードをそのI持っているが、このようなものです:

XMLで

<maintag> 
    <exam chapter="Chapter 1"> 
    <ex id="1">Exam 1</ex> 
    <ex id="2">Exam 2</ex> 
    <ex id="3">Exam 3</ex> 
    </exam> 

    <exam chapter="Chapter 2"> 
    <ex id="4">Exam 1</ex> 
    <ex id="5">Exam 2</ex> 
    </exam> 

    <exam chapter="Chapter 3"> 
    <ex id="6">Exam 1</ex> 
    </exam> 

    <exam chapter="Chapter 4"> 
    <ex id="7">Exam 1</ex> 
    <ex id="8">Exam 2</ex> 
    <ex id="9">Exam 3</ex> 
    <ex id="10">Exam 4</ex> 
    </exam> 
</maintag> 


PHP

<?php 
$xml = DOMDocument::load('examdata.xml'); 
$xpath = new DOMXPath($xml); 
$exams = $xpath->query('//exam/ex'); 

$istyle = 1; //This is to add gray after every other row 

echo "  <table cellpadding=\"0\" cellspacing=\"3\" border=\"0\" width=\"60%\" align=\"center\"> 
      <tr id=\"center\" bgcolor=\"#999\"> 
       <td>Book</td> 
       <td>Exam</td> 
       <td>ID</td> 
       <td>Student's Exam Status</td> 
      </tr> 
"; 

foreach($exams as $exams2) { 
    $chapter = $exams2->parentNode->getAttribute('chapter'); 
    $examid = $exams2->getAttribute('id'); 
    $examname = $exams2->nodeValue; 

    if ($examid < 5) { //where it says 5 there goes a php variable where it has the queried user's exam number from the database, again this is all finished no need to change this. 
     $exstatus = "You already took this exam."; 
    }elseif ($examid == 5) { 
     $exstatus = "This is your exam (exam link)"; 
    }elseif ($examid > 5) { 
     $exstatus = "You are not yet on this exam"; 
    } 

echo "<tr id=\"center\""; 

     if ($istyle % 2 == 0) 
      echo " bgcolor=\"#ccc\""; 

     echo "> 
       <td>$chapter</td> 
       <td>$examname</td> 
       <td>$examid</td> 
       <td>$exstatus</td> 
      </tr>"; 

      $istyle++; 
} 

echo " 
     </table>"; 
?> 

テーブル構造は、私は私がそれをしたいと私は上記のそれを得ていたと述べた方法とは異なることに注意してください、私はそれがあった方法でそれを残すことができなかったので、私はそれを変更しました。

私が変更したいのは、章が書かれている箇所です.1回目と2回目以降の試験を表示するには、一度に表示したいと思います。章の横に次の章(この例では第2章)とその試験の下に1とその試験の下に置く。その後、試験2の下に別のテーブル行を作成し、他の2つの章とその下の他の試験を作成します。

試験はパターンに従って行われていないことに注意してください。これは数百ものファイルがあり、上記のものとは異なる値を持つため編集されたバージョンのファイルです。

上記のコードは機能していますが、自分の要件を満たすことができるように変更したいだけです。配列から項目、代わりに...

foreach($exams as $exams) 

を取得する

答えて

1

私はそれを理解しました、それは時間がかかりましたが、私はついにそれを行いました。

これは私がPHPで使用したコードですが、XMLは同じままです。できるだけ詳細にしようとするので、似たような問題を抱える人を助けることができます。そうすれば、情報を抽出してニーズに合わせて修正することができます。

<?php 
//self explanatory 
$xml = DOMDocument::load('examdata.xml'); 
//again, self explanatory 
$xpath = new DOMXPath($xml); 
//looks for ex under exam in the xml I loaded above xml 
$exams = $xpath->query('//exam/ex'); 
//I just put a number for testing purposes but it actually gets the user's exam id from the database 
$studentexnum = "5"; 
//column counter, will be used to tell that after every 2 chapters, break the table data (td) and table row (tr) and create a new one 
$_2chapters = 1; 
//Opens the table and displays it to the client 
echo "<table cellpadding=\"5\" cellspacing=\"5\" border=\"0\" width=\"25%\" align=\"center\"> 
    <tr>"; //Opens the first table row and end the echoing 

//starts the loop, for every exam, makes exam2 same as exam 
foreach($exams as $exams2) { 
//looks at my xml file for the tag ex (what I defined above) and gets the attribute called chapter from his parent (the tag above it) 
    $chapter = $exams2->parentNode->getAttribute('chapter'); 
//gets the attribute called id from the tag ex 
    $examid = $exams2->getAttribute('id'); 
//makes the tag ex a string so we could display it 
    $examname = $exams2->nodeValue; 

////////////////////////////////////////Now for the Fun Part///////////////////////////////////////////////////////////////////////////////// 

//conditional statement saying that if the variable chapter2 is set, display the conditions below, if it's not set (which is not when its starts the loop) do something else 
    if (isset($chapter2)){ 
//says if variable chapter defined above is equal to variable chapter 2 which is defined below do something. This is not true the first time but it is the rest of the loop, even is is a million. 
      if ($chapter == $chapter2) { 
//variable chaptertd (which is called below) will equal to nothing if chapter equals to chapter2, this will happen at every exam (every ex tag in my xml file which is in the question above) 
//this will avoid having repeated chapter, ie: chapter1 - exam one, chapter1 - exam 2, chapter1 exam 3, ect. will make it chapter 1, exam 1, exam 2, exam 3, ect 
       $chaptertd = ""; 
//if chapter does not equal to chapter2 
       }else { 
//here we increment variable _2chapters that was 1 above, now is two, this is necessary so it could display two chapters side by side and break right before the third chapter, this will happen later 
       $_2chapters++; 
       $chapter2 = $chapter; //THIS PART IS EDITED, BUT NECESSARY 
//Now we give a value to variable chaptertd, it was nothing before because I didn't want to repeat the title every time the loop found a new tag ex from my xml. This will only happen once in every chapter 
       $chaptertd = " 
     </td> 
     <td align=\"center\" valign=\"top\">$chapter2";//here we create the html that variable chaptertd will be displaying after a new name from the attribute chapter is found. This will display the name of the chapter to our table 
       } 
//this else will only happen the first time the loop runs since only the first time is when the variable chapter2 is not defined, after this runs the variable chapter2 will have been defined 
      }else { 
//chapter2 will be the same as chapter, if chapter equals to the string chapter1 so will chapter2. 
       $chapter2 = $chapter; 
//here we create the same td as above since we want to display the name of the chapter the fist time it runs, if we don't do this the first chapter won't be display to the client 
       $chaptertd = " 
     <td align=\"center\" valign=\"top\">$chapter2"; 
      } 
//This part you don't have to concern yourself with it, I made this because I needed it to display different info depending whether the user was allow to see that exam. 
//the variable examval is defined outside this code, that's on my html code which would do nothing here since it uses javascript and css. this gets the attribute id from our ex tag. 
    if ($examid < $studentexnum) { 
     $exval = "lessthan"; 
    }elseif ($examid == 5) { 
     $exval = "equalto"; 
    }elseif ($examid > 5) { 
     $exval = "greaterthan"; 
    } 

//here we say what happens when the variable _2chapters reaches the third attribute called chapter. we say if the remainder of variable _2chapters divided by 3 equals 0 do something 
//else do nothing since we didn't define the else because we didn't needed it. this part will only happen at every third chapter, it will break from the previous chapter thus making 
//it a new row right under the values of the tag ex which is under chapter 1 the third time the loops runs, but this will happen infinite amounts of time, after that it will be under 
//chapter 3 and after that chapter 5 and so on. 
      if ($_2chapters % 3 == 0) { 
//here we reset the count back to one because if we don't and there's more than one tag ex under chapter 3, it will be braking after every ex 
       $_2chapters = 1; 
//here we echo the break from the previous chapter 
      echo " 
     </td> 
    </tr> 
    <tr id=\"center\">"; 
    } 
//here we echo the variable chaptertd which we gave different values to above depending whether the chapter's name has been declared already or not. If it has been declared, chaptertd 
//won't show anything, if the chapter has never been declared it will create a new td and display the chapter's name and after that it will become nothing again 
echo "$chaptertd<br /> 
      <a href=\"#\" class=\"modalInput\" rel=\"#$exval\">$examname</a>";//here we show the client what's the name of the exams under the given chapter, there could be one or one hundred of this and it will only display the chapter once and will display the rest 
//of the exam names one after the other 

//here we say that chapter2 equals to chapter, this way chapter2 will equal to the name of that loop, if the next time it repeats there's a new chapter the value of chapter will change 
//thus making this statement false above and that will force it to create a new td with the new name until another name appears. 
      $chapter2 = $chapter; 
} 

//close the table to have a well formatted html file to display to the client. 
echo " 
     </td> 
    </tr> 
</table>"; 
?> 

私は実際にしばらく前にそれを考え出したが、私は十分なポイントか何かを持っていないので、この「スマートフォーラムは、」私は8時間前に自分の質問に答えることはできません。それは、私がここで新しいので、私は愚かであり、私の問題の解決策を私自身の8時間以内に見つけることができないので、それを言っているかのようなものです。だから私は眠りについた。私は将来この投稿に来るかもしれない他の人々を助けたいと思っていました。そして、うまくいけば答えは彼らの質問のいくつかに答えるでしょう。

+0

あなたのソリューションを共有していることは素晴らしいことです。私はフォーラムの待機期間が理にかなっていると思う。そうでなければ、それは誤用されるからだ。評価点を収集するために、質問を書いてすぐに答えを出すことができます。 – martinstoeckli

0

おそらく意味...

foreach($exams as $exam) 

...ところで私は変数のために他の名前を考えるでしょう試験exの場合は、それらが何であるかを示す名前を使用してください。おそらく試験です。

+0

私が言っているすべてのことは、試験が試験として使われ、試験の価値が下のコードに変わり、試験に合格しなくなったからです。もちろん、それは実際にあなたが言った方法になります。また、var名はデモ専用ですが、デモファイルからこれを引っ張りました。元のファイルから何も変更せずに変更を加えようとしていますが、これはvar試験で別のものに割り当てられていますので、巨大なファイルなので、そのファイルを混乱させたくありません。非常に深いです。しかし、私はあなたの記事を読んでいただきありがとうございます。 – jmc0228

+0

私は何か他のものとして試験から変更する予定です – jmc0228

+0

@ jmc0228 - 申し訳ありませんがあなたの質問を誤解しました。私はグループ化基準を理解していませんが、第1章と第2章はなぜ一緒にグループ化され、第3章と第4章ですか?この2つの章のすべての試験をリストに載せる必要がありますか? – martinstoeckli

関連する問題