2011-12-08 30 views
0

我得到了一個XML文件被PHP回顯並且所有的代碼都能正常工作,但是我的問題是在一個標記內(檢查和屬性是章節,它被回顯)不止一個標籤(例如,這就是被作爲呼應考試#),我的數據呼應了桌上,我希望它是這樣顯示的:PHP,XML,回聲時重複屬性的問題


|第1章|第2章|

| - 考試1 --- | - 考試1 --- |

| - 考試2 --- | - 考試2 --- |

|第3章|第4章|

| - 考試1 --- | - 考試1 --- |


但是我所得到的是這樣的:(我知道爲什麼雖然)


|第1章|

| - 查看1 --- |

|第1章|

| - 考試2 --- |

|第2章|

| - 查看1 --- |


它不斷重複標籤的屬性,我知道爲什麼,因爲我呼應,我有作爲表數據的變量標籤的屬性。所以問題不在於它爲什麼會發生,而是如何將其改變爲以我想要的方式顯示它。

我想也許有刪除的屬性,如果有一個以上的方式(我知道你可以刪除它,但我不知道如何一次顯示它並刪除等)

的代碼,我有是這樣的:

在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章)的下一章中,在考試1下面和考試2下面。然後在考試2下方創建另一個表格行,並放置另外兩個章節,並在其他考試下方。

請注意,考試不遵循模式,這是該文件的編輯版本,因爲其中有數百個,並且這些值與您在上面看到的不同。

上面的代碼工作,我只是想修改它,以便它可以滿足我的要求。

回答

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) 

...從數組中得到一個項目,而不是...

foreach($exams as $exams) 

BTW,我覺得其他的名字來的考試ex,使用描述他們是什麼的名字,可能是考試章節

+0

實際上,我可以通過此代碼獲得所有項目,因爲我所說的是考試將用作考試,考試的價值更改爲下面的代碼,不再是考試的頂部,但它當然是按照你說的方式。此外,var名稱僅用於演示,我從一個演示文件中抽取了該文件,以便進行更改,而不用更改原始文件中的任何內容,因爲它已將var考試指派給其他內容,所以我無法使用該文件,因爲是一個很大的文件,它非常深。但我感謝你閱讀我的文章。 – jmc0228

+0

我會改變它從現在的考試 – jmc0228

+0

@ jmc0228 - 對不起,我誤解了你的問題。雖然我不明白分組標準,但爲什麼第1章和第2章組合在一起,第3章和第4章呢?那麼應該列出這兩章的所有考試嗎? – martinstoeckli