Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Please help, can't figure out nested loop construct. 1

Status
Not open for further replies.

sd0t1

IS-IT--Management
Mar 14, 2007
131
US
I'm reading an .xml file with a nested for each loop. Here is a sample of the xml file

- <GroupHeader1 Type="Header">
<LoginLogoutNotice FieldName="{@Login/Logout Notice}">Jill Doe 1368</LoginLogoutNotice>
</GroupHeader1>
- <Details Type="Details">
<date FieldName="{@date}">2008-03-05</date>
<Time FieldName="{@Time}">07:55:37</Time>
<event_type FieldName="{@event_type}">Login</event_type>
<duration_login FieldName="{@duration_login}">00:00:00</duration_login>
</Details>
- <Details Type="Details">
<date FieldName="{@date}">2008-03-05</date>
<Time FieldName="{@Time}">12:00:25</Time>
<event_type FieldName="{@event_type}">Logout</event_type>
<duration_login FieldName="{@duration_login}">04:04:48</duration_login>
</Details>
- <Details Type="Details">
<date FieldName="{@date}">2008-03-05</date>
<Time FieldName="{@Time}">12:40:07</Time>
<event_type FieldName="{@event_type}">Login</event_type>
<duration_login FieldName="{@duration_login}">00:00:00</duration_login>
</Details>
- <Details Type="Details">
<date FieldName="{@date}">2008-03-05</date>
<Time FieldName="{@Time}">16:30:04</Time>
<event_type FieldName="{@event_type}">Logout</event_type>
<duration_login FieldName="{@duration_login}">03:49:57</duration_login>
</Details>
<total_login FieldName="{@total_login}">07:54:45</total_login>


Here is what the .xml file is displaying.
<groupheader1> (1 incident)
User = Jill Doe

<Details>
(This section should be 4 incidents login in the morning out for lunch login after lunch and out at end of day... Note, some users may not log out for lunch)


date = date
time = time
event = login or logut
duration = how long

<total login>
total duration = total of all time logged in

Ok, I hope that isn't confusing. Now here is my loops

$objDOM = new DOMDocument();
$objDOM->load("newphone.xml"); //make sure path is correct


$note = $objDOM->getElementsByTagName("GroupHeader1");
// for each note tag, parse the document and get values for

foreach( $note as $value )
{

$LoginLogoutNotice = $value->getElementsByTagName("LoginLogoutNotice");
$LoginLogoutNotices = $LoginLogoutNotice->item(0)->nodeValue;

$notes = $objDOM->getElementsByTagName("Details");

foreach ($notes as $value)
{
$date = $value->getElementsByTagName("date");
$dates = $date->item(0)->nodeValue;


$Time = $value->getElementsByTagName("Time");
$Times = $Time->item(0)->nodeValue;

$event_type = $value->getElementsByTagName("event_type");
$event_types = $event_type ->item(0)->nodeValue;

$duration_login = $value->getElementsByTagName("duration_login");
$duration_logins = $duration_login ->item(0)->nodeValue;


}
echo "$LoginLogoutNotices :: $dates :: $event_types :: $Times :: $duration_logins<BR> <br>";
}

I've tried several different variations, but here is what I want it to look like

Jill Doe :3/25/2008 :Login 7:30 : Logout 12:00 : Login 1:00 : Logut 4:30 : total 8:00
John Doe : 3/25/2008 : Login 8:00 : logout 4:30 : total 8:30

and so on, and so on (about 100 staff)
Ultimately I want to enter this in a database.

Thanks in advance.
 
i would recommend NOT using overlapping variables. so in your inner loop instead of foreach ($notes as $value) use foreach ($notes as $somethingelse)

but i can't help thinking that you're making life difficult with xml. why not just put each event into a database as it occurs?
 
That's my ultimate goal, I was just echoing it on the screen first to see it work like I want it to show in the database.
My goal is to have it list in the database 1 row per user, no matter how many times they logged in or out (up to 8) but I can't figure out how to have it read the xml and write to the database correctly. Right now it writes everything on a new row in the database.
Would it be to much to ask you for an example of how you would do it?
 
i was advocating abandoning xml altogether. write the login/logout events directly to the database.

assuming your structure is constant, use this method instead of trying to navigate the DOM

Code:
<?php
$userpattern = '/<LoginLogoutNotice.*?>(.*?)<\/LoginLogoutNotice>/imsx';
$pattern = <<<HTML
/<Details.*?>
\s*<date.*?>(.*?)<\/date> 
\s*<Time.*?>(.*?)<\/Time> 
\s*<event_type.*?>(.*?)<\/event_type> 
\s*<duration_login.*?>(.*?)<\/duration_login> 
\s*<\/Details>/imsx
HTML;


$xml = <<<XML
<GroupHeader1 Type="Header">
  <LoginLogoutNotice FieldName="{@Login/Logout Notice}">Jill Doe 1368</LoginLogoutNotice> 
</GroupHeader1>
<Details Type="Details">
  <date FieldName="{@date}">2008-03-05</date> 
  <Time FieldName="{@Time}">07:55:37</Time> 
  <event_type FieldName="{@event_type}">Login</event_type> 
  <duration_login FieldName="{@duration_login}">00:00:00</duration_login> 
  </Details>
<Details Type="Details">
  <date FieldName="{@date}">2008-03-05</date> 
  <Time FieldName="{@Time}">12:00:25</Time> 
  <event_type FieldName="{@event_type}">Logout</event_type> 
  <duration_login FieldName="{@duration_login}">04:04:48</duration_login> 
  </Details>
<Details Type="Details">
  <date FieldName="{@date}">2008-03-05</date> 
  <Time FieldName="{@Time}">12:40:07</Time> 
  <event_type FieldName="{@event_type}">Login</event_type> 
  <duration_login FieldName="{@duration_login}">00:00:00</duration_login> 
  </Details>
<Details Type="Details">
  <date FieldName="{@date}">2008-03-05</date> 
  <Time FieldName="{@Time}">16:30:04</Time> 
  <event_type FieldName="{@event_type}">Logout</event_type> 
  <duration_login FieldName="{@duration_login}">03:49:57</duration_login> 
</Details>
<total_login FieldName="{@total_login}">07:54:45</total_login> 

XML;

//get the user name
preg_match($userpattern, $xml, $user);
$user = $user[1];

preg_match_all($pattern, $xml, $matches);
//restructure array
$events = array();
foreach ($matches[1] as $key=>$date){
	$events[] = array(
					'name'=>$user,
					'date'=>$date,
					'time'=>$matches[2][$key],
					'event_type'=>$matches[3][$key],
					'duration'=>$matches[4][$key]);
}
echo "<pre>";
print_r($events);
?>
 
Thanks JPadie I appreciate your help, I need to take a moment to figure out how your code is working.
I think one of my problems is that the xml structure isn't how I need it to be.
Ultimately I need to enter this from the report into the database... All on one row

Jill Doe 1368
[date] => 2008-03-05

[time] => 07:55:37
[event_type] => Login
[duration] => 00:00:00
[time] => 12:00:25
[event_type] => Logout
[duration] => 04:04:48
[time] => 12:40:07
[event_type] => Login
[duration] => 00:00:00
[time] => 16:30:04
[event_type] => Logout
[duration] => 03:49:57
[total_login] => 07:54:45

versus now...

[name] => Jill Doe 1368
[date] => 2008-03-05
[time] => 07:55:37
[event_type] => Login
[duration] => 00:00:00
)

[1] => Array
(
[name] => Jill Doe 1368
[date] => 2008-03-05
[time] => 12:00:25
[event_type] => Logout
[duration] => 04:04:48
)

[2] => Array
(
[name] => Jill Doe 1368
[date] => 2008-03-05
[time] => 12:40:07
[event_type] => Login
[duration] => 00:00:00
)

[3] => Array
(
[name] => Jill Doe 1368
[date] => 2008-03-05
[time] => 16:30:04
[event_type] => Logout
[duration] => 03:49:57
 
it would not be sensible to store this kind of data on one row. it is better to store each event as a separate event., roughly as i set out.

but in any event, you can change the shape of the output array by altering the code in the foreach construct.

and i repeat: don't use XML at all. i have only once ever found a decent use for storing data as xml; and that was very specific.
 
Thanks JPadie. I understand.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top