2012-11-02 83 views
1

這是我到目前爲止,我想添加日期/時間日誌到XML文件。XML搜索和addChild

<?php 

     // Load the XML file we want to write to 
      $visitors = simplexml_load_file("data.xml"); 

     // Set e-mail xml search 
      $search_id = htmlentities($_POST['email']); 
      $visitors = $visitors->xpath("visitor[email='$search_id']"); 

     // If we have a search result, email already exists in xml file 
      if(isset($visitors[0])){ 
      $visitor = $visitors[0]; 
      $email = (string) $visitor->email; 

      // ********** Need to add date/time for each visit here. 
      // So, I guess I need to search for e-mail address, then append to it. 
      // Help required here... and again below to confirm formatting for multiple 
      // dates. 

      } else { 
      $xml = simplexml_load_file("data.xml"); 
      $sxe = new SimpleXMLElement($xml->asXML()); 
      $search_id = preg_replace('/[^(\x20-\x7F)]*/','', $search_id); 

      $visitor = $sxe->addChild("visitor"); 
      $visitor->addChild("email", $search_id); 

      // ******** Not sure this is the correct xml formatting. 
       $date = $visitor->addChild('date'); 
       $date->addChild("email", date("Y-m-d H:i:s")); 

      $sxe->asXML("data.xml"); 
      } // if(isset($visitors[0])){ 

     } // if(isset($data)){ ?> 

產生

<?xml version="1.0" encoding="utf-8"?> 
<visitors> 
<visitor> 
    <email>[email protected]</email> 
    </visitor> 
</visitors> 

我想要做的就是添加日期日誌(incementing /追加),每次訪問。

所以結果會是(我不確定我的格式是否正確,哪些當然不起作用)。不要擔心日期/時間的PHP。

<?xml version="1.0" encoding="utf-8"?> 
<visitors> 
<visitor> 
    <email>[email protected]</email> 
    <date>2012-11-01 11:00:00</date> 
    <date>2012-11-02 14:00:00</date> 
    </visitor> 
</visitors> 
+0

相關:[如何使用SimpleXML追加PHP的XML文件](http://stackoverflow.com/q/7098093/367456) – hakre

回答

1

這是一個除了@Geekmans answer

您的代碼不看遠的。然而,你可以大大改善它,這就是爲什麼在這裏添加另一個答案(我通常會編輯@Geekmans回答,但它已經非常大)。

改進的地方在於程序流程。如果找不到電子郵件,則不需要創建新的SimpleXMLElement,只需創建新的<visitor>元素。然後添加<date>元素以及輸出文件對於這兩種情況實際上是相同的。這允許刪除重複的代碼:

// Specify the XML file we want to write to 
$inFile = "data.xml"; 

// Set e-mail xml search and insert id 
$search_id = '[email protected]'; 
$insert_id = preg_replace('/[^(\x20-\x7F)]*/', '', $search_id); 

// Load the XML file we want to write to 
$xmlFile = simplexml_load_file($inFile); 
$results = $xmlFile->xpath("visitor[email='$search_id']"); 

// If we have a search result, email already exists in xml file 
if ($results) { 
    $visitor = $results[0]; 
    echo "Found Visitor: ", $visitor->email, "\n", 
    "First Date: ", $visitor->date, "\n"; 
} else { 
    echo "Adding new Visitor: ", $insert_id, "\n"; 
    $visitor = $xmlFile->addChild("visitor"); 
    $visitor->addChild("email", $insert_id); 
} 

echo "Adding new Date: ", $date = date('Y-m-d H:i:s'), "\n"; 
$visitor->addChild('date', $date); 

echo "Changed XML: \n" . simplexml_pretty_print($xmlFile); 
$xmlFile->asXML($inFile); 


/** 
* @param SimpleXMLElement $simplexml 
* @link https://stackoverflow.com/a/798986/367456 
*/ 
function simplexml_pretty_print(SimpleXMLElement $simplexml) { 
    $dom      = new DOMDocument(); 
    $dom->preserveWhiteSpace = false; 
    $dom->formatOutput  = true; 
    $dom->loadXML($simplexml->asXML()); 
    return $dom->saveXML(); 
} 

當我加入了simplexml_pretty_print功能有一個更好的方式輸出的獎金。

[email protected]輸出:

Found Visitor: [email protected] 
First Date: 2012-11-01 11:00:00 
Adding new Date: 2012-11-03 10:48:05 
Changed XML: 
<?xml version="1.0" encoding="utf-8"?> 
<visitors> 
    <visitor> 
    <email>[email protected]</email> 
    <date>2012-11-01 11:00:00</date> 
    <date>2012-11-02 14:00:00</date> 
    <date>2012-11-03 10:48:05</date> 
    </visitor> 
</visitors> 

[email protected]輸出:

Adding new Visitor: [email protected] 
Adding new Date: 2012-11-03 10:52:09 
Changed XML: 
<?xml version="1.0" encoding="utf-8"?> 
<visitors> 
    <visitor> 
    <email>[email protected]</email> 
    <date>2012-11-01 11:00:00</date> 
    <date>2012-11-02 14:00:00</date> 
    </visitor> 
    <visitor> 
    <email>[email protected]</email> 
    <date>2012-11-03 10:52:09</date> 
    </visitor> 
</visitors> 

提示:當你發現重複的代碼,往往是把它寫在一個更簡單的方式形成。

3

我覺得你在這裏在正確的軌道上,更主要的是,你對asXML通話(「data.xml中」)是你的ELSE塊內,所以文件只被寫入到文件,如果它是從頭開始創建(即沒有找到search_id)。

我做了一些改動,主要是爲了讓它更容易遵循。更多的變化來!:

<?php 

// Load the XML file we want to write to 
$xmlFile = simplexml_load_file("data.xml"); 

// Set e-mail xml search 
$search_id = '[email protected]'; 
$results = $xmlFile->xpath("visitor[email='$search_id']"); 

// If we have a search result, email already exists in xml file 
if(isset($results[0])) 
{ 
    $visitor = $results[0]; 
    $email = (string) $visitor->email; 

    echo "Found Email: " . $email . "\n"; 
    echo "Date: " . $visitor->date . "\n"; 
    // ********** Need to add date/time for each visit here. 
    // So, I guess I need to search for e-mail address, then append to it. 
    // Help required here... and again below to confirm formatting for multiple 
    // dates. 
    echo "Adding new date"; 
    $visitor->addChild('date', date('Y-m-d H:i:s')); 

    echo "New XML: " . $xmlFile->asXML(); 

    $xmlFile->asXML('data.xml'); 

} else { 
    $sxe = new SimpleXMLElement($xmlFile->asXML()); 
    $search_id = preg_replace('/[^(\x20-\x7F)]*/','', $search_id); 

    $visitor = $sxe->addChild("visitor"); 
    $visitor->addChild("email", $search_id); 

    // ******** Not sure this is the correct xml formatting. 
    $date = $visitor->addChild('date', date('Y-m-d H:i:s')); 

    $sxe->asXML("data.xml"); 

} 
?> 

運行此腳本了幾次後,我得到了:

<?xml version="1.0"?> 
<visitors> 
     <visitor> 
       <email>[email protected]</email> 
       <date>2012-11-03 02:13:28</date> 
       <date>2012-11-03 02:20:20</date> 
       <date>2012-11-03 02:22:07</date> 
       <date>2012-11-03 02:22:10</date> 
       <date>2012-11-03 02:22:13</date> 
     </visitor> 
</visitors> 

我認爲這是你想要的嗎?這有幫助嗎?

編輯:

關於你的它是否是正確的XML格式提。我想沒有專有的正確答案。我會說這種格式沒有問題,只要你記得在自己的訪問者標籤中分隔每個單獨的電子郵件地址/一組日期。

要做到這一點,你可能想要的東西,像這樣(未經):

$newVisitor = $xmlFile->addChild('visitor'); 
$newVisitor->addChild('email', $newEmail); 
$newVisotor->addChild('date', $newDate); 
$xmlFile->asXML('data.xml'); 

編輯2:

,我已經在過去使用

最後一件事是以下碼。它將格式化XML更好,並且還可以防止原始XML文件的任何損壞,如果您在保存期間有任何問題(或至少會給您一個備份)。就我個人而言,我試圖習慣於在任何時候需要寫入文件時使用這樣的臨時文件。

當然,只是添加這個,然後更換您的來電:

  • $ xmlFile-> asXML( 'data.xml中');
  • $ sxe-> asXML(「data.xml」);

有了:

  • 中WriteXML( 'data.xml中',$ XMLFILE);
  • writeXML('data.xml',$ sxe);

它應該可以工作。

//Writes final version of the SimpleXML object to file. 
//Includes writing to a temp file for safety. 
//This way is safer because if the code crashes mid-write it won't garble the original file. 
function writeXML($fileName, $xmlObject) 
{ 
     //Sanity check before copy, prevent any visible errors: 
     if (file_exists($fileName)) 
       copy($fileName, $fileName . '.backup'); 

     //Write to temp file first in-case something kills the write; don't want to corrupt the original. 
     $tmpName = $fileName . '~$.' . microtime(); 
     $handle = fopen($tmpName, 'w'); 
     fwrite($handle, formatXML($xmlObject)); 
     fclose($handle); 
     copy($tmpName, $fileName); 
     unlink($tmpName); 
} 

//asXML does no indentation formatting, so we'll do it here instead. This is called by WriteXML so that we're writing formatted XML to file. 
function formatXML($xmlObject) 
{ 
     $dom = new DOMDocument('1.0'); 
     $dom->preserveWhiteSpace = false; 
     $dom->formatOutput = true; 
     $dom->loadXML($xmlObject->asXML()); 
     return $dom->saveXML(); 
} 
+0

你是一個英雄......我剛剛開始循環與foreach ......並不認爲這是正確的方法,顯然它不是! – Stuart

+0

讓我知道如果有什麼我可以在這裏協助。我想提供一些代碼來正確格式化XML時寫入文件...但不幸的是它還沒有工作。 :( – Geekman

+0

百萬謝謝你.. – Stuart