我已经使用带有数字键的simplexml从已解析的xml文件创建了多维数组,但我希望它们被命名为键而不是数字。
xml文件如下:
<workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" >
<Worksheet ss:Name="tab1">
<Table>
<Row>
<Cell><Data>Id</Data></Cell> // names which i want to be array keys.
<Cell><Data>Company</Data></Cell> //
<Cell><Data>Year</Data></Cell> //
</Row>
<Row>
<Cell><Data>120</Data></Cell> //values
<Cell><Data>Apple</Data></Cell>
<Cell><Data>2011</Data></Cell>
</Row>
<Row>
<Cell><Data>121</Data></Cell>
<Cell><Data>Samsung</Data></Cell>
<Cell><Data>2010</Data></Cell>
</Row>
</Table>
</Worksheet>
<Worksheet ss:Name="tab2">
<Table>
<Row>
<Cell><Data>Id</Data></Cell>
<Cell><Data>Company</Data></Cell>
<Cell><Data>Year</Data></Cell>
</Row>
<Row>
<Cell><Data>320</Data></Cell>
<Cell><Data>Sony</Data></Cell>
<Cell><Data>2001</Data></Cell>
</Row>
<Row>
<Cell><Data>321</Data></Cell>
<Cell><Data>HTC</Data></Cell>
<Cell><Data>2001</Data></Cell>
</Row>
</Table>
</Worksheet>
</workbook>
她是我解析xml文件和创建数组的代码
$xml=simplexml_load_file($fileData);
$result= array();
$i=0;
foreach($xml->Worksheet as $worksheet ):
$result['tab'][$i] = array();
$result['tab'][$i]['name']=(string)$worksheet->attributes("ss", true)->Name;
foreach($worksheet as $table):
$k =0;
unset($table->Row[0]); //removing first row which i want to be keys of array
foreach($table as $row):
foreach($row as $cell):
$result['tab'][$i]['data'][$k][] =(string)$cell->Data;
endforeach;
$k++;
endforeach;
endforeach;
$i++;
endforeach;
return $result;
我得到的数组:
Array
(
[tab] => Array
(
[0] => Array
(
[name] => tab1
[data] => Array
(
[0] => Array
(
[0] => 120 //keys should be name of first row of xml
[1] => Apple
[2] => 2011
)
[1] => Array
(
[0] => 121
[1] => Samsung
[2] => 2010
)
)
)
[1] => Array
(
[name] => tab2
[data] => Array
(
[0] => Array
(
[0] => 320
[1] => Sony
[2] => 2001
)
[1] => Array
(
[0] => 321
[1] => HTC
[2] => 2001
)
)
)
)
)
我希望数组如下:
Array
(
[tab] => Array
(
[0] => Array
(
[name] => tab1
[data] => Array
(
[0] => Array
(
[Id] => 120 // named keys instead of numbers
[Company] => Apple
[Year] => 2011
)
[1] => Array
(
[Id] => 121
[Company] => Samsung
[Year] => 2010
)
)
)
[1] => Array
(
[name] => tab2
[data] => Array
(
[0] => Array
(
[Id] => 320
[Company] => Sony
[Year] => 2001
)
[1] => Array
(
[Id] => 321
[Company] => HTC
[Year] => 2001
)
)
)
)
)
这是一个有点长的问题。但很好解释。 谢谢。答案 0 :(得分:3)
将每个表行转换为数组,然后将第一行用作后续行的键:
$table_to_array = function(SimpleXMLElement $table) {
$keyed = function($table) {
$keys = NULL;
foreach ($table->Row as $row) {
$array = array_map('trim', $row->xpath('Cell/Data'));
$keys ? (yield array_combine($keys, $array))
: $keys = $array;
}
};
return iterator_to_array($keyed($table));
};
$xml = simplexml_load_file($path_to_xml_file);
$array = $table_to_array($xml->Worksheet->Table);
print_r($array);
输出:
Array
(
[0] => Array
(
[Id] => 120
[Company] => Apple
[Year] => 2011
)
[1] => Array
(
[Id] => 121
[Company] => Samsung
[Year] => 2010
)
)
将它应用于任意数量的表格。
如果你有PHP&lt; 5.5然后你还不能使用Generators,但是,你仍然可以使用迭代器。这或多或少只意味着您需要编写更多代码:
// this example uses some code from:
// https://github.com/hakre/Iterator-Garden/blob/master/src/IndexIteration.php
require_once 'IndexIteration.php';
class TableRowIterator extends IteratorIterator
{
public function __construct(SimpleXMLElement $table) {
parent::__construct(new IndexIteration($table->Row));
}
public function current() {
return array_map('trim', parent::current()->xpath('Cell/Data'));
}
public function key() {
return $this->getInnerIterator()->getIndex();
}
}
class KeyedArrayIterator extends IteratorIterator
{
private $keys;
public function rewind()
{
parent::rewind();
$this->keys = parent::current();
parent::next();
}
public function current()
{
return array_combine($this->keys, parent::current());
}
}
$table_to_array = function($table) {
$rows = new TableRowIterator($table);
$keyed = new KeyedArrayIterator($rows);
return iterator_to_array($keyed);
};
$xml = simplexml_load_file($path_to_xml_file);
$array = $table_to_array($xml->Worksheet->Table);
print_r($array);
正如它所示,更多的代码行,但处理数据的方式相同。将KeyedArrayIterator
与the commented answer中的CSVFile
Iterator类进行比较,就是这种处理方式:将第一行用作所有后续行的键。
输出与使用生成器的PHP 5.5示例完全相同。