1

这是我到目前为止所拥有的,我想将日期/时间日志添加到 xml 文件中。

   <?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>jon.doe@aol.com</email>
  </visitor>
</visitors>

我想要做的是为每次访问添加一个日期日志(增加/附加)。

所以结果是(我不确定我的格式是否正确,这当然无济于事)。不要担心日期/时间的 PHP。

<?xml version="1.0" encoding="utf-8"?>
<visitors>
 <visitor>
  <email>jon.doe@aol.com</email>
  <date>2012-11-01 11:00:00</date>
  <date>2012-11-02 14:00:00</date>
  </visitor>
</visitors>
4

2 回答 2

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 = 'jon.doe@aol.com';
$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>jon.doe@aol.com</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();
}
于 2012-11-02T15:26:18.643 回答
1

这是@Geekmans 答案的补充

你的代码看起来并不太远。但是,您可以大大改进它,这就是为什么在这里添加另一个答案(我通常会编辑@Geekmans 答案,但它已经非常大了)。

改进点在于程序流程。如果没有找到email,不需要新建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 = 'jon.doe@aol.com';
$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功能以更好地输出。

的输出jon.doe@aol.com

Found Visitor: jon.doe@aol.com
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>jon.doe@aol.com</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>

的输出info@example.com

Adding new Visitor: info@example.com
Adding new Date: 2012-11-03 10:52:09
Changed XML: 
<?xml version="1.0" encoding="utf-8"?>
<visitors>
  <visitor>
    <email>jon.doe@aol.com</email>
    <date>2012-11-01 11:00:00</date>
    <date>2012-11-02 14:00:00</date>
  </visitor>
  <visitor>
    <email>info@example.com</email>
    <date>2012-11-03 10:52:09</date>
  </visitor>
</visitors>

提示:每当您发现重复代码时,通常有一种方法可以以更简单的形式编写它。

于 2012-11-03T09:53:23.980 回答