Twoje pytanie jest naprawdę szerokie, najlepszą odpowiedzią, jaką mogę dać, jest to, że powinieneś użyć jakiejś istniejącej biblioteki do kodowania XML zamiast pisać własną (ponieważ oczywiście nie udaje ci się wykonać zadania, stąd błąd kodowania XML zgłoszony przez użytkownika XML).
Korzystanie z istniejącej biblioteki pozwoliłoby również na wcześniejsze wskazywanie problemów. Np. dla poniższego kodu upewnij się, że wszystko, co otrzymasz z bazy danych, to ciągi zakodowane w UTF-8.
Również użycie bardziej nowoczesnej klasy klienta bazy danych pomoże ci w znacznym stopniu po prostu napisać kod. Oto przykład z PDO
i 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();
Zobacz, że DomDocument
dba o prawidłowe zakodowanie ciągów znaków UTF-8, które są zwracane z bazy danych. Nie ma (zwykle) potrzeby <![CDATA[...]]>
tu dłużej. Jak możesz sobie wyobrazić, prawdopodobnie umieściłeś tam coś, co zepsuło twoje kodowanie XML.
Również w przypadku interakcji z bazą danych większość kodu nie jest potrzebna, możesz po prostu iterować po wierszach, jeśli nie ma wierszy, nie byłoby iteracji. Najlepiej jest to wyrazić za pomocą Iterator
foreach
może działać konstrukcja języka, na którym zapewniają nowoczesne interfejsy baz danych. Technicznie możesz zastąpić $rows
tutaj z wieloma innymi rzeczami, takimi jak iterator, który przechodzi przez wiele tabel jedna po drugiej.
Dodatkowo użycie trybu błędu wyjątku pozwala zaoszczędzić na dokonywaniu kontroli i die
s w całej bazie kodu.
Przykładowe wyjście to:
<?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>
Jeśli nadal musisz tworzyć elementy CDATA, działa to podobnie (pokazuję tutaj tylko część skryptu, który zawiera tylko niewielką modyfikację dodając sekcje CDATA zamiast wartości podrzędnej):
### 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))
;
}
}
Również tutaj, DOMDocument
dba o prawidłowe zakodowanie sekcji CDATA. Coś, czego prawdopodobnie nie zrobiłeś.
Potencjalne problemy, które nadal możesz napotkać, dotyczą nazw tabel lub wierszy, które są nieprawidłowe nazwy XML
. Ale wtedy DOMDocument
faktycznie powie ci, abyś wiedział podczas generowania XML, a nie tylko później z błędem kodowania.