我正试图找出一种更加动态地填充XML对象的方法,而无需不断更改节点的名称。我的一些代码与此类似:
编辑:将数据更改为与实际数据库结构内联:
$query = ("Select order_id, created_on, updated_on, status from table orders;");
// Execute query
$result = mysql_query($query, $link) or die("Could not complete database query");
// Populate array
while(($resultArray[] = mysql_fetch_assoc($result)) || array_pop($resultArray));
$doc = new DOMDocument();
$doc->formatOutput = true;
$r = $doc->createElement( "data" );
$doc->appendChild( $r );
foreach( $resultArray as $record )
{
$b = $doc->createElement( "record" );
$record1 = $doc->createElement( "Order" );
$record1->appendChild(
$doc->createTextNode( $record['order_id'] )
);
$b->appendChild( $record1 );
$record2 = $doc->createElement( "Created" );
$record2->appendChild(
$doc->createTextNode( $record['created_on'] )
);
$b->appendChild( $record2 );
$record3 = $doc->createElement( "Updated" );
$record3->appendChild(
$doc->createTextNode( $record['updated_on'] )
);
$b->appendChild( $record3 );
$record4 = $doc->createElement( "Status" );
$record4->appendChild(
$doc->createTextNode( $record['status'] )
);
$b->appendChild( $record4 );
$r->appendChild( $b );
}
echo $doc->saveXML();
// Close connection
mysql_close($link);
这很好,但如果我想在查询中添加第3列,我还必须将它添加到循环中。我确信有更好的方法来实现这一点。
有什么建议吗?
感谢。
答案 0 :(得分:0)
我会做那样的事情:
$elemColMap = array(
'Column1' => 'First_Column',
'Column2' => 'Second_Column',
);
foreach( $resultArray as $record )
{
$b = $doc->createElement( "record" );
foreach($elemColMap as $xmlElem => $dbCol) {
$record1 = $doc->createElement( $xmlElem );
$record1->appendChild(
$doc->createTextNode( $record[$dbCol] )
);
$b->appendChild( $record1 );
}
$r->appendChild( $b );
}
答案 1 :(得分:0)
你可以这样做:
$column_num = 1;
foreach ( $record as $r_key => $r_value )
{
if (!preg_match('/_Column$/', $r_key)
continue;
$xml_record = $doc->createElement( "Column".$column_num );
$xml_record->appendChild(
$doc->createTextNode( $r_value )
);
$b->appendChild( $xml_record );
$column_num++;
}
当然,您还没有给我们确切的数据库结构,所以我假设您要添加的列以_Column
结尾(这就是!preg_match('/_Column$/', $r_key)
的原因)。如果您想要所有列,只需在循环开始时删除这两行。
答案 2 :(得分:0)
也许我写的这门课会帮助你...
<?PHP
class ArrayTo
{
protected static function array2xml($xml, $arr, $elements)
{
foreach($arr as $key => $value)
{
$element = isset($elements[0]) ? $elements[0] : $key;
if(is_array($value))
{
$xml->startElement($element);
self::array2xml($xml, $value, array_slice($elements, 1));
$xml->endElement();
continue;
}
$xml->writeElement($element, $value);
$elements = array_slice($elements, 1);
}
}
public static function xml($arr, $root = 'root', $elements = Array(), $version = '1.0', $encoding = 'UTF-8')
{
$xml = new XMLWriter();
$xml->openMemory();
$xml->startDocument($version, $encoding);
$xml->startElement($root);
self::array2xml($xml, $arr, $elements);
$xml->endElement();
return $xml->outputMemory(true);
}
}
?>
如何使用它......
$data = array(
"column1" => "im column 1",
"column2" => "im column 2",
"column3" => "im column 3",
"column4" => "im column 4",
"column5" => "im column 5",
);
echo ArrayTo::xml($data, 'table');
// output
<?xml version="1.0" encoding="UTF-8"?>
<table>
<column1>im column 1</column1>
<column2>im column 2</column2>
<column3>im column 3</column3>
<column4>im column 4</column4>
<column5>im column 5</column5>
</table>
您还可以使用第三个参数$elements
使用自定义元素覆盖该级别的$ key。例如......
echo ArrayTo::xml($data, 'table', array('COLUMN_1', 'COLUMN_2'));
// output
<?xml version="1.0" encoding="UTF-8"?>
<table>
<COLUMN_1>im column 1</COLUMN_1>
<COLUMN_2>im column 2</COLUMN_2>
<column3>im column 3</column3>
<column4>im column 4</column4>
<column5>im column 5</column5>
</table>