Greetings,

I am trying to write XML using SimpleXML for a web service call. I was having success until the XML got a little more complicated. Here is the XML format where I am running into problems:

<Agent>
    <Person Last='Smith' First='John'>
        <Addresses />
        <PhoneNumbers>
            <Phone Type='1' Number='888-555-1212'>
        </PhoneNumbers>
    </Person>
</Agent>

Here is my php:

$xmlOutput = new SimpleXMLElement('<?xml version="1.0"?><ReportRequest> </ReportRequest>');
$xmlOutput->addAttribute('CID','9200');
$xmlOutput->addAttribute('Diagram','1');
$xmlOutput->addAttribute('DueDate','2011-11-15');
$xmlOutput->addAttribute('NumPhotos','6');
$xmlOutput->addAttribute('InspectAfter','');
$xmlOutput->addAttribute('PolicyNumber','JTC0004425');
$reportType = $xmlOutput->addChild('ReportType');
$reportType->addAttribute('CPType','Commercial');
$reportType->addAttribute('SectionIDs','');
$reportType->addAttribute('Description','');
$reportType->addAttribute('ReportTypeID','123');
$locations =  $xmlOutput->addChild('Locations')->addChild('Addresses')->addChild('Address');
$locations->addAttribute('Zip','91216');
$locations->addAttribute('City','Chatsworth');
$locations->addAttribute('Line1','123 Main St');
$locations->addAttribute('Line2','Suite 201');
$locations->addAttribute('State','CA');
$locations->addAttribute('Latitude','');
$locations->addAttribute('Longitude','');
$agent =  $xmlOutput->addChild('Agent')->addChild('Person')->addChild('Addresses')->addChild('PhoneNumbers')->addChild('Phone');
$agent->addAttribute('Last','Smith');
$agent->addAttribute('Email','');
$agent->addAttribute('First','John');
$agent->addAttribute('Title','');
$agent->addAttribute('Type','1');
$agent->addAttribute('Number','888-555-1212');
$agent->addAttribute('TypeName','Office');
$agent->addAttribute('Extension','');

Header('Content-type: text/xml');

echo $xmlOutput->asXML();

Everything outputs as it should until the line that starts with $agent. I want the output to match the section above. I have tried several variations but I cannot seem to figure it out. I know the current PHP sample doesn't work. Help??

Thanks in advance,

John

Recommended Answers

All 9 Replies

Member Avatar for jmichae3

you are missing the standard XML header.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ul SYSTEM "http://nowhere.com/menu7-breadcrumb.dtd">

the 2nd line is optional, it is the file location or URL to the DTD which defines the elements used in the document. there are very informative books on writing DTD's, I suggest one that is written specifically for the task because anything else will be a handwaving/gloss-over.
on that 2nd line, ul is the outer container element (doesn't have to be ul, could be library). your XML tags must be contained within that single outer element.

incorrect call to the constructor probably. 1st argument is the filepath.
http://us3.php.net/manual/en/simplexmlelement.construct.php

Member Avatar for jmichae3

if you comment out the first line, php is interpreting the ?> in the xml header as a close of the PHP code block.
personally I think this is a bug in PHP, since this is in a string.
it's header() instead of Header(). PHP is case sensitive if I am not mistaken.

<?php
//$xmlobj = new SimpleXMLElement('<!DOCTYPE ReportRequest SYSTEM "ReportRequest.dtd">');
$xmlobj = new SimpleXMLElement('');
$xmlmain = $xmlobj->addChild('ReportRequest');
$xmlmain->addAttribute('CID','9200');
$xmlmain->addAttribute('Diagram','1');
$xmlmain->addAttribute('DueDate','2011-11-15');
$xmlmain->addAttribute('NumPhotos','6');
$xmlmain->addAttribute('InspectAfter','');
$xmlmain->addAttribute('PolicyNumber','JTC0004425');
$reportType = $xmlmain->addChild('ReportType');
$reportType->addAttribute('CPType','Commercial');
$reportType->addAttribute('SectionIDs','');
$reportType->addAttribute('Description','');
$reportType->addAttribute('ReportTypeID','123');
$locationsaddr = $xmlmain->addChild('Locations')->addChild('Addresses')->addChild('Address');
$locationsaddr->addAttribute('Zip','91216');
$locationsaddr->addAttribute('City','Chatsworth');
$locationsaddr->addAttribute('Line1','123 Main St');
$locationsaddr->addAttribute('Line2','Suite 201');
$locationsaddr->addAttribute('State','CA');
$locationsaddr->addAttribute('Latitude','');
$locationsaddr->addAttribute('Longitude','');
$agentphone = $xmlmain->addChild('Agent')->addChild('Person')->addChild('Addresses')->addChild('PhoneNumbers')->addChild('Phone');
$agentphone->addAttribute('Last','Smith');
$agentphone->addAttribute('Email','');
$agentphone->addAttribute('First','John');
$agentphone->addAttribute('Title','');
$agentphone->addAttribute('Type','1');
$agentphone->addAttribute('Number','888-555-1212');
$agentphone->addAttribute('TypeName','Office');
$agentphone->addAttribute('Extension','');
 
header('Content-type: text/xml');
echo $xmlobj->asXML();
?>

you must be messing with a fairly young api. I have more debugging to do.

Member Avatar for jmichae3

one of the things you need to do is when you have a child that starts leaf nodes in a tree structure (has children or attributes), you need to assign that child to a variable so you can do the addChild() and addAttribute() method calls.
the line with the phrase NO ERRORS is not being output. this means that the creation of the SimpleXMLElement is failing.
I discovered that failure can happen after every line in which no errors occur, but code suddenly stops executing - learned this through inserting debug echo statements.
http://us3.php.net/manual/en/simplexml.examples-basic.php

<!--
<Agent>
   <Person Last='Smith' First='John'>
		<Addresses />
		<PhoneNumbers>
			<Phone Type='1' Number='888-555-1212'>
		</PhoneNumbers>
   </Person>
</Agent>
-->
<?php
//$xmlobj = new SimpleXMLElement('<!DOCTYPE ReportRequest SYSTEM "ReportRequest.dtd">');
//anything you want at the top  of xml output you put in the quotes

$reportRequest = new SimpleXMLElement('<ReportRequest></ReportRequest>'); 

$reportRequest->addAttribute('CID','9200');
$reportRequest->addAttribute('Diagram','1');
$reportRequest->addAttribute('DueDate','2011-11-15');
$reportRequest->addAttribute('NumPhotos','6');
$reportRequest->addAttribute('InspectAfter','');
$reportRequest->addAttribute('PolicyNumber','JTC0004425');

$reportType = $reportRequest->addChild('ReportType'); //leaf node of ReportRequest
$reportType->addAttribute('CPType','Commercial');
$reportType->addAttribute('SectionIDs','');
$reportType->addAttribute('Description','');
$reportType->addAttribute('ReportTypeID','123');

$locsAddr = $reportRequest->addChild('Locations')->addChild('Addresses')->addChild('Address'); //leaf node of Addresses
$locsAddr->addAttribute('Zip','91216');
$locsAddr->addAttribute('City','Chatsworth');
$locsAddr->addAttribute('Line1','123 Main St');
$locsAddr->addAttribute('Line2','Suite 201');
$locsAddr->addAttribute('State','CA');
$locsAddr->addAttribute('Latitude','');
$locsAddr->addAttribute('Longitude','');

$agentPerson = $reportRequest->addChild('Agent')->addChild('Person'); //leaf nodes of Agent
$agentPerson->addAttribute('Last','Smith');
$agentPerson->addAttribute('Email','');
$agentPerson->addAttribute('First','John');
$agentPerson->addAttribute('Title','');
 
$agentPersonAddrs = $agentPerson->addChild('Addresses'); //leaf node of Person
//we could have thrown away the object this returned because we
//are not assigning any attributes or doing any children.

$agentPhone = $agentPerson->addChild('PhoneNumbers')->addChild('Phone'); //leaf nodes of Person
$agentPhone->addAttribute('Type','1');
$agentPhone->addAttribute('Number','888-555-1212');
$agentPhone->addAttribute('TypeName','Office');
$agentPhone->addAttribute('Extension','');
 
header('Content-type: text/xml');
echo $reportRequest->asXML(); //dump xml
?>
<?xml version="1.0"?>
<ReportRequest CID="9200" Diagram="1" DueDate="2011-11-15" NumPhotos="6" InspectAfter="" PolicyNumber="JTC0004425">
	<ReportType CPType="Commercial" SectionIDs="" Description="" ReportTypeID="123"/>
	<Locations>
		<Addresses>
			<Address Zip="91216" City="Chatsworth" Line1="123 Main St" Line2="Suite 201" State="CA" Latitude="" Longitude=""/>
		</Addresses>
	</Locations>
	<Agent>
		<Person Last="Smith" Email="" First="John" Title="">
			<Addresses/>
			<PhoneNumbers>
				<Phone Type="1" Number="888-555-1212" TypeName="Office" Extension=""/>
			</PhoneNumbers>
		</Person>
	</Agent>
</ReportRequest>
Member Avatar for jmichae3

SimpleXML is not the same class as SimpleXMLElement. that tutorial is about a different class, but it is nice to have anyway.

SimpleXML is not the same class as SimpleXMLElement. that tutorial is about a different class, but it is nice to have anyway.

Did you even bother to read it? I have read and printed it, it is all about SimpleXML.
BTW SimpleXML is a package which contain SimpleXMLElement. So far that is simplest and best tut I have seen on the subject!

Member Avatar for jmichae3

then is SimpleXMLElement derived from SimpleXML, or is SimpleXML derived from SimpleXMLElement, or are they both separate classes? I am not sure I could read the PHP source code from the tarball.

I had thought that maybe SimpleXMLElement was derived from SimpleXML, but the documentation does not say anything.

then is SimpleXMLElement derived from SimpleXML, or is SimpleXML derived from SimpleXMLElement, or are they both separate classes? I am not sure I could read the PHP source code from the tarball.

I had thought that maybe SimpleXMLElement was derived from SimpleXML, but the documentation does not say anything.

The name says it, it is an element of SimpleXML. See this section that deals with that

Member Avatar for jmichae3

so SimpleXML appears to be derived from SimpleXMLElement... judging from teh kind of array data content it puts out. interesting. the autho9r of the article didn't say anything about derivation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.