Jump to content

SimpleXML with nested tag attributes


soycharliente

Recommended Posts

I'm trying to use http://www.php.net/manual/en/simplexml.examples-basic.php to parse some XML for insertion into a MySQL database.

 

Looking at Example #5, I see that I can reference a tag with a specific attribute, but in the example XML code, that tag has no child tags. How can I access a tag AND reference it's attribute and then dive deeper into it's child attributes?

 

Code that returns error:

Warning: Invalid argument supplied for foreach() in /home/content/c/h/a/charlieholder/html/iac/index.php on line 21

<?php
foreach ($xml->Group->Group->Details->Section->Field['ADDRESS'] as $group_level_1)
{
echo $group_level_1->Value, '<br />';
}
?>

 

XML Document structure:

// Report

//  Group Level="1" (only one)

//  Group Level="2" (multiple)

//    Details Level="3" (multiple)

//    Section SectionNumber="0" (only one)

//      Field Name="various-things" (multiple)

//      Value (only one)

Link to comment
https://forums.phpfreaks.com/topic/185493-simplexml-with-nested-tag-attributes/
Share on other sites

Can you give us an example of the XML document (the structure above is ambiguous, even though you probably didn't mean it that way) and what you're trying to extract from it? It looks like you're nearly there, though not quite and with specific details we might only guide you further away from the best result!

<?xml version="1.0" encoding="UTF-8" ?>
<Report>
<Group Level="1">
<Group Level="2">
	<Details Level="3">
		<Section SectionNumber="0">
			<Field Name="FIRSTNAME"><FormattedValue>F1</FormattedValue><Value>F1</Value></Field>
			<Field Name="MIDDLENAME"><FormattedValue>M1</FormattedValue><Value>M1</Value></Field>
			<Field Name="LASTNAME"><FormattedValue>L1</FormattedValue><Value>L1</Value></Field>
			<Field Name="ADDRESS"><FormattedValue>123 Street</FormattedValue><Value>123 Street</Value></Field>
			<Field Name="ADDRESSCITY"><FormattedValue>Atlanta</FormattedValue><Value>Atlanta</Value></Field>
			<Field Name="ADDRESSSTATE"><FormattedValue>GA</FormattedValue><Value>GA</Value></Field>
			<Field Name="ADDRESSZIP"><FormattedValue>30313</FormattedValue><Value>30313</Value></Field>
			<Field Name="EMAIL"><FormattedValue>[email protected]</FormattedValue><Value>[email protected]</Value></Field>
			<Field Name="PHONE"><FormattedValue>(555)555- 5555</FormattedValue><Value>(555)555- 5555</Value></Field>
		</Section>
	</Details>
	<Details Level="3">
		<Section SectionNumber="0">
			<Field Name="FIRSTNAME"><FormattedValue>F2</FormattedValue><Value>F2</Value></Field>
			<Field Name="MIDDLENAME"><FormattedValue>M2</FormattedValue><Value>M2</Value></Field>
			<Field Name="LASTNAME"><FormattedValue>L2</FormattedValue><Value>L2</Value></Field>
			<Field Name="ADDRESS"><FormattedValue>123 Street</FormattedValue><Value>123 Street</Value></Field>
			<Field Name="ADDRESSCITY"><FormattedValue>Atlanta</FormattedValue><Value>Atlanta</Value></Field>
			<Field Name="ADDRESSSTATE"><FormattedValue>GA</FormattedValue><Value>GA</Value></Field>
			<Field Name="ADDRESSZIP"><FormattedValue>30313</FormattedValue><Value>30313</Value></Field>
			<Field Name="EMAIL"><FormattedValue>[email protected]</FormattedValue><Value>[email protected]</Value></Field>
			<Field Name="PHONE"><FormattedValue>(555)555- 5555</FormattedValue><Value>(555)555- 5555</Value></Field>
		</Section>
	</Details>
</Group>
<Group Level="2">
	<Details Level="3">
		<Section SectionNumber="0">
			<Field Name="FIRSTNAME"><FormattedValue>F3</FormattedValue><Value>F3</Value></Field>
			<Field Name="MIDDLENAME"><FormattedValue>M3</FormattedValue><Value>M3</Value></Field>
			<Field Name="LASTNAME"><FormattedValue>L3</FormattedValue><Value>L3</Value></Field>
			<Field Name="ADDRESS"><FormattedValue>123 Street</FormattedValue><Value>123 Street</Value></Field>
			<Field Name="ADDRESSCITY"><FormattedValue>Atlanta</FormattedValue><Value>Atlanta</Value></Field>
			<Field Name="ADDRESSSTATE"><FormattedValue>GA</FormattedValue><Value>GA</Value></Field>
			<Field Name="ADDRESSZIP"><FormattedValue>30313</FormattedValue><Value>30313</Value></Field>
			<Field Name="EMAIL"><FormattedValue>[email protected]</FormattedValue><Value>[email protected]</Value></Field>
			<Field Name="PHONE"><FormattedValue>(555)555- 5555</FormattedValue><Value>(555)555- 5555</Value></Field>
		</Section>
	</Details>
	<Details Level="3">
		<Section SectionNumber="0">
			<Field Name="FIRSTNAME"><FormattedValue>F4</FormattedValue><Value>F4</Value></Field>
			<Field Name="MIDDLENAME"><FormattedValue>M4</FormattedValue><Value>M4</Value></Field>
			<Field Name="LASTNAME"><FormattedValue>L4</FormattedValue><Value>L4</Value></Field>
			<Field Name="ADDRESS"><FormattedValue>123 Street</FormattedValue><Value>123 Street</Value></Field>
			<Field Name="ADDRESSCITY"><FormattedValue>Atlanta</FormattedValue><Value>Atlanta</Value></Field>
			<Field Name="ADDRESSSTATE"><FormattedValue>GA</FormattedValue><Value>GA</Value></Field>
			<Field Name="ADDRESSZIP"><FormattedValue>30313</FormattedValue><Value>30313</Value></Field>
			<Field Name="EMAIL"><FormattedValue>[email protected]</FormattedValue><Value>[email protected]</Value></Field>
			<Field Name="PHONE"><FormattedValue>(555)555- 5555</FormattedValue><Value>(555)555- 5555</Value></Field>
		</Section>
	</Details>
</Group>
<Group Level="2">
	<Details Level="3">
		<Section SectionNumber="0">
			<Field Name="FIRSTNAME"><FormattedValue>F5</FormattedValue><Value>F5</Value></Field>
			<Field Name="MIDDLENAME"><FormattedValue>M5</FormattedValue><Value>M5</Value></Field>
			<Field Name="LASTNAME"><FormattedValue>L5</FormattedValue><Value>L5</Value></Field>
			<Field Name="ADDRESS"><FormattedValue>123 Street</FormattedValue><Value>123 Street</Value></Field>
			<Field Name="ADDRESSCITY"><FormattedValue>Atlanta</FormattedValue><Value>Atlanta</Value></Field>
			<Field Name="ADDRESSSTATE"><FormattedValue>GA</FormattedValue><Value>GA</Value></Field>
			<Field Name="ADDRESSZIP"><FormattedValue>30313</FormattedValue><Value>30313</Value></Field>
			<Field Name="EMAIL"><FormattedValue>[email protected]</FormattedValue><Value>[email protected]</Value></Field>
			<Field Name="PHONE"><FormattedValue>(555)555- 5555</FormattedValue><Value>(555)555- 5555</Value></Field>
		</Section>
	</Details>
	<Details Level="3">
		<Section SectionNumber="0">
			<Field Name="FIRSTNAME"><FormattedValue>F6</FormattedValue><Value>F6</Value></Field>
			<Field Name="MIDDLENAME"><FormattedValue>M6</FormattedValue><Value>M6</Value></Field>
			<Field Name="LASTNAME"><FormattedValue>L6</FormattedValue><Value>L6</Value></Field>
			<Field Name="ADDRESS"><FormattedValue>123 Street</FormattedValue><Value>123 Street</Value></Field>
			<Field Name="ADDRESSCITY"><FormattedValue>Atlanta</FormattedValue><Value>Atlanta</Value></Field>
			<Field Name="ADDRESSSTATE"><FormattedValue>GA</FormattedValue><Value>GA</Value></Field>
			<Field Name="ADDRESSZIP"><FormattedValue>30313</FormattedValue><Value>30313</Value></Field>
			<Field Name="EMAIL"><FormattedValue>[email protected]</FormattedValue><Value>[email protected]</Value></Field>
			<Field Name="PHONE"><FormattedValue>(555)555- 5555</FormattedValue><Value>(555)555- 5555</Value></Field>
		</Section>
	</Details>
</Group>
</Group>
</Report>

Here's a few different ways of getting at the right Values.

 

// 1. Ugly way
foreach ($xml->Group->Group as $group) {
foreach ($group->Details as $detail) {
	foreach ($detail->Section as $section) {
		foreach ($section->Field as $field) {
			if ($field['Name'] == 'ADDRESS') {
				echo $field->Value . "\n";
			}
		}
	}
}
}

// 2. Nice way
foreach ($xml->xpath('/Report/Group/Group/Details/Section/Field[@Name="ADDRESS"]/Value') as $value) {
echo $value . "\n";
}

// 2a. Shorter, nice way
foreach ($xml->xpath('//Field[@Name="ADDRESS"]/Value') as $value) {
echo $value . "\n";
}

Ended up using your suggestions as a base and going with:

<?php
foreach ($xml->Group->Group->Details->Section->Field as $path)
{
$field = $path['Name'];
switch($field)
{
	case 'ONE':
	case 'TWO':
	//... etc.
	case 'TWENTY':
		$array[$field] = $path->Value;
		break;
	default:
		//do nothing
		break;
}
}
?>

 

Thanks for the help.

Sorry about this. Rather than start a new thread without any back story, I thought continuing here would make more sense.

 

I'm getting an error:

Warning: Illegal offset type in /home/content/c/h/a/charlieholder/html/iac/index.php on line 52

 

From reading the manual about arrays, I gather that this error is thrown when "Arrays and objects are used as keys." I don't think that either of my referenced variables are arrays or objects. I'm pretty sure that $i is an integer and $field is a string, so I don't know why the error is being thrown. Unless the error is coming from somewhere else and I'm not getting it.

 

Any ideas?

 

<?php
$data = array();
$i = 0;

foreach ($xml->Group->Group->Details->Section as $level_1)
{
foreach ($level_1->Field as $level_2)
{
	$field = $level_2['Name'];
	switch($field)
	{
		case 'FIRSTNAME':
			$data[$i][$field] = $level_2->Value; //LINE 52
			break;
		default:
			//do nothing
			break;
	}
}
$i++;
}
print_r($data);
?>

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.