2013-12-23 43 views
3

我試圖創建一個基於時間條件的通訊。我有一個XML文件加載到DOM文檔中。使用php遍歷不同的DOM節點和元素

<?xml version="1.0"?> 
<users> 
<user><mail>[email protected]</mail><time>1387814834</time></user><user>  <mail>[email protected]</mail><time>1387814834</time></user></users> 

我想遍歷所有的'時間'標籤,也從每個'郵件'標籤的值作爲一個字符串。

這是我第一次嘗試。我不知道爲什麼我在這裏失敗,但似乎迭代工作正常,但留下郵件。

$data = new DOMDocument(); 

$data->load('data.xml'); 

$times = $data->getElementsByTagName('time'); 
$emails = $data->getElementsByTagName('mail'); 

$timestamp = time(); 
$timestamp1 = $timestamp; 
$timestamp = $timestamp-1; 

foreach($times as $t) 

{ 

    if($t->nodeValue > $timestamp) 

    { 

    } 

    else if($t->nodeValue < $timestamp) 

{ 

$t->nodeValue = $timestamp1; 

$email = $emails->nodeValue; 

$to = $email; 

這是我第二次嘗試。這裏的問題是$電子郵件不能轉換爲字符串。

$itm = 0; 

require_once('functions.php'); 

$data = new DOMDocument(); 

$data->load('data.xml'); 

$times = $data->getElementsByTagName('time'); 

$timestamp = time(); 
$timestamp1 = $timestamp; 
$timestamp = $timestamp-1; 

foreach($times as $t) 

{ 

    if($t->nodeValue > $timestamp) 

    { 
    $itm = $itm+1; 
    } 

    else if($t->nodeValue < $timestamp) 

{ 

$t->nodeValue = $timestamp1; 

$email1 = $data->getElementsByTagName('mail')->item($itm); 

$email = strval($email1); 

$itm = $itm+1; 

$to = $email; 

$unsub = base64_encode($email); 

任何想法,我可以做到這一點?謝謝你的幫助!

回答

0

一個for循環可能更合適:

$times = $data->getElementsByTagName('time'); 
$emails = $data->getElementsByTagName('mail'); 

for ($i=0; $i < $times->length; $i++) { 
    $ts = (string) $times->item(0)->nodeValue; 
    if ($ts < time()-1) { 
     $times->item(0)->nodeValue = $ts; 
     $email = $emails->item(0)->nodeValue; 
    } 
} 

Demo.

+0

內部項目只有索引()丟失:P,但是這是溶液許多感謝 – user3130117

+0

['//用戶/時間[數<1387896441] /前同輩(。) ::郵件[最後()]'](http://stackoverflow.com/a/20762674/367456) – hakre

0

我覺得這種方式會更可讀:

<?php 
$x='<?xml version="1.0"?> 
<users> 
<user><mail>[email protected]</mail><time>1387814834</time></user> 
<user>  <mail>[email protected]</mail><time>1387814834</time></user></users>'; 
$doc = new DOMDocument(); 
$doc->loadXML($x); 

foreach ($doc->getElementsByTagName('user') as $user){ 
    $mails = $user->getElementsByTagName('mail'); 
    $times = $user->getElementsByTagName('time'); 
    print $mails->item(0)->nodeValue. "-". $times->item(0)->nodeValue ."\n"; 
} 

你可以試一下:https://eval.in/82242

0

我修改了Amal代碼,這只是我需要什麼。

$times = $data->getElementsByTagName('time'); 
$emails = $data->getElementsByTagName('mail'); 

$timestamp = time(); 

for ($i=0; $i < $times->length; $i++) { 
$ts = (string) $times->item($i)->nodeValue; 
if ($ts < $timestamp-1) { 
    $times->item($i)->nodeValue = $timestamp; 
    $email = $emails->item($i)->nodeValue; 

$to = $email; 
0

您想要以字符串的形式訪問XML元素(也許屬性)。您選擇了PHP的DOMDocument庫來解析XML。 DOM is a standard defined by W3C不僅被PHP使用,還被其他許多人使用,例如Mozilla。

要獲得DOM文檔元素的字符串值,你需要訪問一個DOMElement對象(PHP:DOMElement::$nodeValue)的nodeValue財產實際上是DOMNode(PHP:DOMNode::$noveValue)的一部分,DOMElement是分型DOMNode。 PHP手冊說,關於nodeValue

的nodeValue
這個節點取決於其類型

通過類型的值,這意味着,如果類型爲DOMElement(如您情況),它將包含你正在尋找的字符串。

因此,所有你需要做的是來查詢preceed那些時間元素更大所有這些電子郵件元素(在我的例子我翻轉這樣的:低於)的時間來比較:

$doc = new DOMDocument; 
$doc->loadXML($xml); 
$xpath = new DOMXpath($doc); 

$expr = sprintf(
    '//user/time[number(.) < %d]/preceding-sibling::mail[last()]' 
    , time() 
); 
echo '"', $expr, "\" :\n"; 

$emails = $xpath->query($expr); 
foreach($emails as $email) { 
    echo ' * ', $email->nodeValue, "\n"; 
} 

如本例所示$email->nodeValue包含電子郵件地址作爲字符串。與典型輸出比較:

"//user/time[number(.) < 1387896441]/preceding-sibling::mail[last()]" : 
* [email protected] 
* [email protected] 

演示是在這裏:https://eval.in/82540


因爲你在你的問題有XML,它最有可能更容易訪問具有不同(但相關)的XML解析器PHP有:SimpleXML。用下面的例子比較:

$doc = simplexml_load_string($xml); 

$expr = sprintf(
    '//user/time[number(.) < %d]/preceding-sibling::mail[last()]' 
    , time() 
); 

$emails = $doc->xpath($expr); 
foreach($emails as $email) { 
    echo ' * ', $email, "\n"; 
} 

如本例所示,提供的SimpleXML神奇__toString()方法使得用於電子郵件中的元素對象 - $email - 與echo使用時被自動轉換爲字符串。

演示是在這裏:https://eval.in/82545