array structure bug/issue w/XML_Unserializer
| From: | Erik Heerlein | Date: | Sat, 30 Oct 2004 22:59:18 +0000 |
| Subject: | array structure bug/issue w/XML_Unserializer | ||
| Groups: | php.pear.general | ||
| Request: | Send a blank email to pear-general+get-15238@lists.php.net to get a copy of this message | ||
From: erik@pixiedustgifts.com
Subject: array structure bug/issue w/XML_Unserializer
Date: October 30, 2004 6:55:19 PM EDT
To: pear-general@lists.php.net
I'm using XML_Serializer to unserialize XML from the United States Post Office APIs for shipping rates. Here's a sample XML response when trying to get a rate for one package.
<RateResponse>
<Package ID="myself">
<Service>Priority</Service>
<ZipOrigination>20770</ZipOrigination>
<ZipDestination>09021</ZipDestination>
<Pounds>5</Pounds>
<Ounces>1</Ounces>
<Container>None</Container>
<Size>REGULAR</Size>
<Machinable>FALSE</Machinable>
<Zone>3</Zone>
<Postage>7.90</Postage>
</Package>
</RateResponse>
And here is what you get when you unserialize it.
array (
'Package' =>
array (
'ID' => 'myself',
'Service' => 'First Class',
'ZipOrigination' => '29487',
'ZipDestination' => '29412',
'Pounds' => '0',
'Ounces' => '1',
'Container' => 'NONE',
'Size' => 'REGULAR',
'Machinable' => 'FALSE',
'Zone' => '1',
'Postage' => '0.37',
),
)
All fine and dandy, I can work with that. Now, here's the response when trying to get the rates for the same package but shipped 2 different ways.
<RateResponse>
<Package ID="myself">
<Service>First Class</Service>
<ZipOrigination>29487</ZipOrigination>
<ZipDestination>29487</ZipDestination>
<Pounds>0</Pounds>
<Ounces>1</Ounces>
<Container>NONE</Container>
<Size>REGULAR</Size>
<Machinable>FALSE</Machinable>
<Zone>1</Zone>
<Postage>0.37</Postage>
</Package>
<Package ID="myself">
<Service>EXPRESS</Service>
<ZipOrigination>29487</ZipOrigination>
<ZipDestination>29487</ZipDestination>
<Pounds>0</Pounds>
<Ounces>1</Ounces>
<Container>NONE</Container>
<Size>REGULAR</Size>
<Machinable>FALSE</Machinable>
<Zone>1</Zone>
<Postage>13.65</Postage>
</Package>
</RateResponse>
And here is what you get when you unserialize it.
array (
'Package' =>
array (
0 =>
array (
'ID' => 'myself',
'Service' => 'First Class',
'ZipOrigination' => '29487',
'ZipDestination' => '29412',
'Pounds' => '0',
'Ounces' => '1',
'Container' => 'NONE',
'Size' => 'REGULAR',
'Machinable' => 'FALSE',
'Zone' => '1',
'Postage' => '0.37',
),
1 =>
array (
'ID' => 'myself',
'Service' => 'EXPRESS',
'ZipOrigination' => '29487',
'ZipDestination' => '29412',
'Pounds' => '0',
'Ounces' => '1',
'Container' => 'NONE',
'Size' => 'REGULAR',
'Machinable' => 'FALSE',
'Zone' => '1',
'Postage' => '13.65',
),
),
)
See the difference? Notice how the second version now contains numerically indexed arrays while the first version did not? In short, the array structure is different for one <Package> tag than it is for two <Package> tags. I don't know if it is intended to work that way or not but I found it quite surprising and nearly impossible to loop through to get the data out if the array structure varies.
I noticed someone else posted this issue and the suggestion was to use an "if/else" construct. A workable solution to me would be to make everything like the second example and have indexed arrays no matter the number of <Package> tags so for one package the result would be:
array (
'Package' =>
array (
0 =>
array (
'ID' => 'myself',
'Service' => 'First Class',
'ZipOrigination' => '29487',
'ZipDestination' => '29412',
'Pounds' => '0',
'Ounces' => '1',
'Container' => 'NONE',
'Size' => 'REGULAR',
'Machinable' => 'FALSE',
'Zone' => '1',
'Postage' => '0.37',
),
),
)
and the structure would be consistent every time.
- Erik Heerlein