Reputation: 21
Example :
<school>
<students>
<student idNumber="123" enrollmentNo="E101">
<name>
<firstname>Jack</firstname>
<lastname>Harmor</lastname>
<standard>7th</standard>
</name>
</student>
<student idNumber="243">
<name>
<firstname>Cris</firstname>
<lastname>Warner</lastname>
<standard>5th</standard>
</name>
</student>
<student idNumber="345">
<name>
<firstname>Rick</firstname>
<lastname>Corner</lastname>
<standard>6th</standard>
</name>
</student>
</students>
<fees type="teaching">
<fifth>100</fifth>
<sixth>110</sixth>
<seventh>120</seventh>
</fees>
</school>
I want to create an array like below
array(
[students_student_name_firstname0]=>Jack,
[students_student_name_lastname0]=>Harmor,
[students_student_name_standard0]=>7th,
[students_student_name_firstname1]=>Cris,
[students_student_name_lastname1]=>Warner,
[students_student_name_standard1]=>5th,
[students_student_name_firstname2]=>Rick,
[students_student_name_lastname2]=>Corner,
[students_student_name_standard2]=>6th,
[students_fifth0]=>100,
[students_sixth0]=>110,
[students_seventh0]=>120,
[attributes]=>array(
[student0]=>array(
[idNumber]=>123,
[enrollmentNo]=>E101
),
[student1]=>array(
[idNumber]=>243
),
[student2]=>array(
[idNumber]=>345
)
)
);
Above is example that this kind of XML may be send to get data, but problem is there is any number of level of XML may be level 1,2,3,..,N so how can i get all data in single/two dimensional array as above(it means limited level of array) and what is the easiest way to store its key names and values and attribute names and its values for the particular tag dynamically? Or if you have any better way to do this then you can also share. I have no more knowledge about that so please help me. Thanks in advance.
Upvotes: 0
Views: 122
Reputation: 631
For a direct conversion to an array and you can handle it in a loop as you wish you can simply do:
$array = json_decode(json_encode(simplexml_load_string($xml)), true);
However, if you want to flatten as much as possible then you can do something extra like so:
$xml = '
<school>
<students>
<student idNumber="123" enrollmentNo="E101">
<name>
<firstname>Jack</firstname>
<lastname>Harmor</lastname>
<standard>7th</standard>
</name>
</student>
<student idNumber="243">
<name>
<firstname>Cris</firstname>
<lastname>Warner</lastname>
<standard>5th</standard>
</name>
</student>
<student idNumber="345">
<name>
<firstname>Rick</firstname>
<lastname>Corner</lastname>
<standard>6th</standard>
</name>
</student>
</students>
<fees type="teaching">
<fifth>100</fifth>
<sixth>110</sixth>
<seventh>120</seventh>
</fees>
</school>
';
$array = json_decode(json_encode(simplexml_load_string($xml)), true);
$result = [];
foreach ($array['students']['student'] as $element) {
$data = [];
foreach ($element as $elements) {
foreach ($elements as $k => $v) {
$data[$k] = $v;
}
}
$result[] = $data;
}
$fees = [];
foreach ($array['fees'] as $k => $v) {
if ($k == '@attributes') {
foreach ($v as $attr => $val) {
$fees[$attr] = $val;
}
} else {
$fees[$k] = $v;
}
}
$result['fees'] = $fees;
echo '<pre>';
print_r($result);
Result:
Array
(
[0] => Array
(
[idNumber] => 123
[enrollmentNo] => E101
[firstname] => Jack
[lastname] => Harmor
[standard] => 7th
)
[1] => Array
(
[idNumber] => 243
[firstname] => Cris
[lastname] => Warner
[standard] => 5th
)
[2] => Array
(
[idNumber] => 345
[firstname] => Rick
[lastname] => Corner
[standard] => 6th
)
[fees] => Array
(
[type] => teaching
[fifth] => 100
[sixth] => 110
[seventh] => 120
)
)
Upvotes: 1
Reputation: 57131
To be able to get all of the text nodes with a value in (i.e. exclude the normal whitespace in any document) and all of the attributes, you can use the following code. Note that this doesn't give you the same format as you give, but the format should allow you to come up with something your after..
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->load($file);
$xp = new DOMXPath($xml);
$entries = $xp->query("//node()[not(node())][string-length(normalize-space(.) ) > 1]");
foreach ( $entries as $data ) {
echo $data->getNodePath()."=".$data->nodeValue.PHP_EOL;
}
echo "Attributes".PHP_EOL;
$attributes = $xp->query("//@*");
foreach ( $attributes as $data ) {
echo $data->getNodePath()."=".$data->nodeValue.PHP_EOL;
}
Gives...
/school/students/student[1]/name/firstname/text()=Jack
/school/students/student[1]/name/lastname/text()=Harmor
/school/students/student[1]/name/standard/text()=7th
/school/students/student[2]/name/firstname/text()=Cris
/school/students/student[2]/name/lastname/text()=Warner
/school/students/student[2]/name/standard/text()=5th
/school/students/student[3]/name/firstname/text()=Rick
/school/students/student[3]/name/lastname/text()=Corner
/school/students/student[3]/name/standard/text()=6th
/school/fees/fifth/text()=100
/school/fees/sixth/text()=110
/school/fees/seventh/text()=120
Attributes
/school/students/student[1]/@idNumber=123
/school/students/student[1]/@enrollmentNo=E101
/school/students/student[2]/@idNumber=243
/school/students/student[3]/@idNumber=345
/school/fees/@type=teaching
You will probably want to trim off some of the parts of the name (i.e. text()
) etc.
Although it would be much better to stick with processing the XML as is.
Upvotes: 0