2013-12-23 3 views
3

Я пытаюсь создать информационный бюллетень на основе времени. У меня есть XML-файл, загруженный в документ DOM.Итерации через различные узлы и элементы DOM с помощью php

<?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; 

Это моя вторая попытка. Проблема здесь в том, что $ 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.

Чтобы получить строковое значение элемента с DOMDocument, вы должны получить доступ к nodeValue свойство DOMElement объекта (PHP: DOMElement::$nodeValue), который фактически является частью DOMNode (PHP: DOMNode::$noveValue) как DOMElement является подтип от DOMNode. PHP руководство говорит о nodeValue:

nodeValue
Значение этого узла, в зависимости от его типа

По типа это означает, что если тип DOMElement (как в вашем case), он будет содержать строку, которую вы ищете.

Так все, что вам нужно сделать, это запросить все эти электронной почты элементы, которые предшествовать эти время элементы, которые больше (в моем примере я переворачивать это: ниже), чем время для сравнения:

$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 автоматически преобразуются в строку.

Demo здесь: https://eval.in/82545

Смежные вопросы