Reputation: 313
I have this lovely chunk of text found inside an XML element and want to convert it into a simple array, the XML is from wikia.com.
The array would be something like this:
card name => [Martial] Ares, character name => Ares, release_date => May 1 2013 and so on..
I've tried all sorts of imploding and exploding variations but no luck.. This one has got me stumped..
|card name=[Martial] Ares
|character name=Ares
|release_date=May 1 2013
|image 1=MartialAres5.jpg
|rarity 1=Super Special Rare
|pwr req 1=28
|sale price 1=94200
|max card lv 1=60
|max mastery lv 1=40
|quote 1=Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear. But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.
|base atk 1=2440
|base def 1=2650
|max atk 1=7015
|max def 1=7613
|mastery bonus atk 1=915
|mastery bonus def 1=993
|image 2=MartialAres6.jpg
|rarity 2=Ultimate Rare
|sale price 2=188400
|max mastery lv 2=200
|quote 2=Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.
|max atk 2=9822
|max def 2=10660
|mastery bonus atk 2=1098
|mastery bonus def 2=1192
|alignment=Bruiser
|ability=Warhawk
|gender=Male
|usage=Average
|faction=Super Hero
|effect=Significantly harden DEF of your Bruisers.
|centretrait=None
Code I've tried:
if (file_exists('card.xml')) {
$xml = simplexml_load_file('card.xml');
$text = $xml->page->revision->text;
$newtext = explode('|', $text);
foreach($newtext as $newnewtext) {
$newtext2 = explode('=', $newnewtext);
print_r($newtext2);
}
} else {
exit('Failed to open card.xml.');
}
Upvotes: 1
Views: 219
Reputation: 10130
@Dagon is correct. This is how an implementation might look:
<?php
$keyvalues = array();
$text = file_get_contents('path/to/your/file');
$rows = explode('|',$text);
foereach($rows as $row) {
if (strpos($row,'=')) {
$kv = array_map('trim',explode('=',$row));
$keyvalues[ $kv[0] ] = $kv[1];
}
}
?>
Upvotes: 0
Reputation:
as requested:
<?php
$file="|card name=[Martial] Ares
|character name=Ares
|release_date=May 1 2013
|image 1=MartialAres5.jpg
|rarity 1=Super Special Rare
|pwr req 1=28
|sale price 1=94200
|max card lv 1=60
|max mastery lv 1=40
|quote 1=Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear. But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.
|base atk 1=2440
|base def 1=2650
|max atk 1=7015
|max def 1=7613
|mastery bonus atk 1=915
|mastery bonus def 1=993
|image 2=MartialAres6.jpg
|rarity 2=Ultimate Rare
|sale price 2=188400
|max mastery lv 2=200
|quote 2=Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.
|max atk 2=9822
|max def 2=10660
|mastery bonus atk 2=1098
|mastery bonus def 2=1192
|alignment=Bruiser
|ability=Warhawk
|gender=Male
|usage=Average
|faction=Super Hero
|effect=Significantly harden DEF of your Bruisers.
|centretrait=None";
$x=explode("\n",$file);
$out=array();
foreach($x as $each){
$xx=explode('=',$each);
$out[ltrim($xx[0],'|')]=$xx[1];
}
echo '<pre>';
print_r($out);
working demo: http://codepad.viper-7.com/3BkXD6
Upvotes: 5
Reputation: 40909
The simplest and most efficient way to achieve that is using regular expressions. Given that $string holds the data, do the following:
preg_match_all('/^\|(?<key>[^=]+)=(?<value>.*)$/m', $string, $matches);
print_r(array_combine($matches['key'], $matches['value']));
For the data you provided as an example you'll get:
Array
(
[card name] => [Martial] Ares
[character name] => Ares
[release_date] => May 1 2013
[image 1] => MartialAres5.jpg
[rarity 1] => Super Special Rare
[pwr req 1] => 28
[sale price 1] => 94200
[max card lv 1] => 60
[max mastery lv 1] => 40
...and so on
)
Upvotes: 1
Reputation: 3157
With the minimal error checking:
$text = explode('|', $text);
$result = array();
foreach ($text as $entry) {
if ($entry) {
$entry = explode('=', $entry);
$result[$entry[0]] = $entry[1];
}
}
Upvotes: 0
Reputation: 1630
First, I would split the string on the '|' charater.
$parts = explode("|", $str);
This will result in an array like the following:
Array
(
[0] =>
[1] => card name=[Martial] Ares
[2] => character name=Ares
[3] => release_date=May 1 2013
[4] => image 1=MartialAres5.jpg
[5] => rarity 1=Super Special Rare
[6] => pwr req 1=28
[7] => sale price 1=94200
[8] => max card lv 1=60
[9] => max mastery lv 1=40
[10] => quote 1=Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear. But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.
[11] => base atk 1=2440
[12] => base def 1=2650
[13] => max atk 1=7015
[14] => max def 1=7613
[15] => mastery bonus atk 1=915
[16] => mastery bonus def 1=993
[17] => image 2=MartialAres6.jpg
[18] => rarity 2=Ultimate Rare
[19] => sale price 2=188400
[20] => max mastery lv 2=200
[21] => quote 2=Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.
[22] => max atk 2=9822
[23] => max def 2=10660
[24] => mastery bonus atk 2=1098
[25] => mastery bonus def 2=1192
[26] => alignment=Bruiser
[27] => ability=Warhawk
[28] => gender=Male
[29] => usage=Average
[30] => faction=Super Hero
[31] => effect=Significantly harden DEF of your Bruisers.
[32] => centretrait=None
)
Next, I would loop over the array and split each string on the "=" character and build an associative array from the pieces.
//First remove the first empty element from the array.
array_shift($parts);
$finalArray = array();
foreach($parts as $part)
{
$b = explode("=", $part);
$finalArray[$b[0]] = $b[1];
}
This should result in the structure you are seeking.
Array
(
[card name] => [Martial] Ares
[character name] => Ares
[release_date] => May 1 2013
[image 1] => MartialAres5.jpg
[rarity 1] => Super Special Rare
[pwr req 1] => 28
[sale price 1] => 94200
[max card lv 1] => 60
[max mastery lv 1] => 40
[quote 1] => Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear. But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.
[base atk 1] => 2440
[base def 1] => 2650
[max atk 1] => 7015
[max def 1] => 7613
[mastery bonus atk 1] => 915
[mastery bonus def 1] => 993
[image 2] => MartialAres6.jpg
[rarity 2] => Ultimate Rare
[sale price 2] => 188400
[max mastery lv 2] => 200
[quote 2] => Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.
[max atk 2] => 9822
[max def 2] => 10660
[mastery bonus atk 2] => 1098
[mastery bonus def 2] => 1192
[alignment] => Bruiser
[ability] => Warhawk
[gender] => Male
[usage] => Average
[faction] => Super Hero
[effect] => Significantly harden DEF of your Bruisers.
[centretrait] => None
)
Upvotes: 0
Reputation: 59691
This should work for you:
First explode()
your string by a new line. Then go through each element with array_map()
and explode the substr()
with an offset of 1 by an equal sign.
At the end just use array_column()
to use the first column as value and the 0 column as key.
$arr = array_column(array_map(function($v){
return explode("=", substr($v, 1));
}, explode(PHP_EOL, $str)), 1, 0);
print_r($arr);
Upvotes: 0