Заполните XML циклами - PullRequest
       1

Заполните XML циклами

0 голосов
/ 05 августа 2011

Я пытаюсь найти способ более динамического заполнения объекта 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-й столбец в запрос, я должен также добавить его в цикл. Я уверен, что есть лучший способ сделать это.

Какой совет?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 05 августа 2011

Вы можете сделать:

$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 строки в начале цикла.

РЕДАКТИРОВАТЬ: черт, я опоздал на 16 секунд: <</p>

0 голосов
/ 05 августа 2011

Может быть, этот класс, который я написал, поможет вам ...

<?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, чтобы переопределить ключ $ на уровне с помощью пользовательского элемента. Например, ...

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>
0 голосов
/ 05 августа 2011

Я бы сделал что-то подобное:

$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 );  
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...