1

I have a piece of XML which is as follows

<records count="2">
  <record>
    <firstname>firstname</firstname>
    <middlename>middlename</middlename>
    <lastname>lastname</lastname>
    <namesuffix/>
    <address>
      <street-number>demo</street-number>
      <street-pre-direction/>
      <street-name>demo</street-name>
      <street-post-direction/>
      <street-suffix>demo</street-suffix>
      <city>demo</city>
      <state>NY</state>
      <zip>demo</zip>
      <zip4>demo</zip4>
      <county>demo</county>
    </address>
    <phonenumberdetails>
      <phonenumber>demo</phonenumber>
      <listed>demo</listed>
      <firstname>demo</firstname>
    </phonenumberdetails>
    <dob day="" month="" year=""/>
    <age/>
    <date-first month="10" year="1999"/>
    <date-last month="04" year="2011"/>
  </record>
  <record>
    <firstname>firstname</firstname>
    <middlename>middlename</middlename>
    <lastname>lastname</lastname>
    <namesuffix/>
    <address>
      <street-number>demo</street-number>
      <street-pre-direction/>
      <street-name>demo</street-name>
      <street-post-direction/>
      <street-suffix>demo</street-suffix>
      <city>demo</city>
      <state>NY</state>
      <zip>demo</zip>
      <zip4>demo</zip4>
      <county>demo</county>
    </address>
    <phonenumberdetails>
      <phonenumber>demo</phonenumber>
      <listed>demo</listed>
      <firstname>demo</firstname>
    </phonenumberdetails>
    <dob day="" month="" year=""/>
    <age/>
    <date-first month="10" year="1999"/>
    <date-last month="04" year="2011"/>
  </record>
</records>

Now, I have been able to get all the data in PHP using SimpleXML except for the date-first and date-last elements. I have been using code listed below

$dateFirst           = 'date-first';
$dateLast            = 'date-last';
$streetNumber        = 'street-number';
$streetPreDirection  = 'street-pre-direction';
$streetName          = 'street-name';
$streetPostDirection = 'street-post-direction';
$streetSuffix        = 'street-suffix';
$unitDesignation     = 'unit-designation';
$unitNumber          = 'unit-number';

foreach ($reportDataXmlrecords->records->record as $currentRecord) {
    echo $currentRecord->$dateFirst['month'].'/'.$currentRecord->$dateFirst['year'];
    echo $currentRecord->$dateLast['month'].'/'.$currentRecord->$dateLast['year'];
    echo $currentRecord->address->$streetNumber;
    $currentRecord->address->$streetName; // ......and so on 
}

where $reportDataXmlrecords is the part of the simpleXML object from the parent node of

But the first two echo's don't print anything and all the other are printing correctly, specifically, I cant access the data in

<date-first month="10" year="1999"/>
<date-last month="04" year="2011"/>

Also for debugging if I do

print_r($currentRecord->$dateFirst);

it prints

SimpleXMLElement Object ( 
    [@attributes] => Array ( [month] => 10 [year] => 1999 ) 
)

Any help would be greatly appreciated. Thank you.

3
  • I guess this question will need some formatting help. Commented Apr 29, 2011 at 15:09
  • what do you get if you var_dump date-first and date-last instead of echo? Commented Apr 29, 2011 at 15:19
  • @GordonM If I do var_dump($currentRecord->$dateFirst); I get object(SimpleXMLElement)#32 (1) { ["@attributes"]=> array(2) { ["month"]=> string(2) "10" ["year"]=> string(4) "1999" } } Commented Apr 29, 2011 at 15:25

1 Answer 1

1

You problem is when you do

$currentRecord->$dateFirst['month']

PHP will first evaluate $dateFirst['month'] as a whole before trying to use it as a property

$dateFirst = 'date-first';
var_dump( $dateFirst['month'] ); // gives "d"

because strings can be accessed by offset with array notation, but non-integer offsets are converted to integer and because casting 'month' to integer is 0, you are trying to do $currentRecord->d:

$xml = <<< XML
<record>
    <date-first month="jan"/>
    <d>foo</d>
</record>
XML;

$record = simplexml_load_string($xml);
$var    = 'date-first';
echo $record->$var['month']; // foo

You can access hyphenated properties with curly braces:

$record->{'date-first'}['month'] // jan

On a sidenote, when the XML shown in your question is really the XML you are loading with SimpleXml, e.g. when <records> is the root node, then doing

$reportDataXmlrecords->records->record

cannot work, because $reportDataXmlrecords is already the root node and you'd have to omit the ->records if you want to iterate over the record elements in it.

Sign up to request clarification or add additional context in comments.

1 Comment

thats right, <records> is not the root node, I will add the correction to the question. And thanks for the great answer , its great, I learnt a new thing. Just to mention by $record->{'dateFirst'}['month'] // jan, I think you meant $record->{'date-first'}['month'] // jan , the second instance worked for me. Maybe it was a typo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.