Въпросът ви е наистина широк, най-добрият отговор, който мога да дам, е, че трябва да използвате някаква съществуваща библиотека, за да кодирате XML, вместо да пишете своя собствена (тъй като очевидно се проваляте с работата, следователно грешката в XML кодирането, докладвана от консумацията на XML).
Използването на съществуваща библиотека също би ви позволило да посочите проблеми по-рано. напр. за следния код се уверете, че всичко, което получавате от вашата база данни, са низове, кодирани с UTF-8.
Също така използването на по-модерен клиентски клас на база данни също ще ви помогне в голяма степен просто да запишете кода. Ето пример с PDO
и DOMDocument
:
### configuration values
$config = array(
'Database' => array(
'dsn' => 'mysql:dbname=test;host=localhost;charset=utf8',
'user' => 'testuser',
'pass' => 'test',
),
'table_name' => 'config',
'table_fields' => '*',
);
### implement database access
class Database extends PDO
{
public function __construct(array $config = null)
{
$config = $config ? : $GLOBALS['config'][__CLASS__];
parent::__construct($config['dsn'], $config['user'], $config['pass']);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
}
}
### setup the datasource ($rows)
$db = new Database();
$rows = $db->query("SELECT $config[table_fields] FROM $config[table_name]");
### setup the XML encoder ($doc)
$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadXML("<$config[table_name]s/>");
$doc->encoding = 'utf-8';
### fetch data from the datasource and encode the XML
foreach ($rows as $row) {
$child = $doc->createElement($config['table_name']);
$child = $doc->documentElement->appendChild($child);
foreach ($row as $key => $value) {
$child->appendChild($doc->createElement($key, $value));
}
}
### output XML
header("Content-Type:text/xml");
echo $doc->saveXML();
Вижте този DomDocument
тук се грижи за правилното кодиране на низовете UTF-8, които се връщат от базата данни. Няма (обикновено) няма нужда от <![CDATA[...]]>
тук вече. Както можете да си представите, вероятно сте поставили нещо там, което е нарушило вашето XML кодиране.
Също така за взаимодействието с базата данни, по-голямата част от вашия код също не е необходима, можете просто да преглеждате редовете, ако няма редове, няма да има итерация. Това обикновено се изразява най-добре с Iterator
foreach
езиковата конструкция може да работи върху която се осигурява от съвременните интерфейси на базата данни. Технически можете да замените $rows
тук с много други неща, като итератор, който преминава през множество таблици една след друга.
Освен това използването на режима за грешка при изключение ви спестява да поставяте проверки и die
е в цялата ви кодова база.
Примерен изход е:
<?xml version="1.0" encoding="utf-8"?>
<configs>
<config>
<id>1</id>
<option>value for option with ID1</option>
</config>
<config>
<id>2</id>
<option>value for option with ID2</option>
</config>
...
</configs>
Ако след това все още трябва да създадете CDATA елементи, той работи по подобен начин (тук показвам само част от скрипта, който съдържа само лека модификация, добавяща CDATA секции вместо дъщерна стойност):
### fetch data from the datasource and encode the XML
foreach ($rows as $row) {
$child = $doc->createElement($config['table_name']);
$child = $doc->documentElement->appendChild($child);
foreach ($row as $key => $value) {
$child->appendChild($doc->createElement($key))
->appendChild($doc->createCDATASection($value))
;
}
}
Тук също DOMDocument
се грижи за правилното кодиране на секцията CDATA. Нещо, което вероятно не сте направили.
Потенциалните проблеми, които все още може да срещнете, са с имена на таблици или редове, които са невалидни XML имена
. Но след това DOMDocument
всъщност ще ви каже, за да знаете, докато генерирате XML, а не само след това с грешка в кодирането.