Je vraag is erg breed, het beste antwoord dat ik kan geven is dat je een bestaande bibliotheek moet gebruiken om de XML te coderen in plaats van je eigen te schrijven (omdat je duidelijk faalt met de taak, vandaar de XML-coderingsfout gerapporteerd door de XML-consument).
Door een bestaande bibliotheek te gebruiken, kunt u ook eerder op problemen wijzen. bijv. voor de volgende code moet je ervoor zorgen dat alles wat je terugkrijgt van je database UTF-8-gecodeerde strings zijn.
Ook het gebruik van een modernere database-clientklasse zal u ook helpen om de code gewoon op te schrijven. Hier is een voorbeeld met PDO
en 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();
Zie dat DomDocument
zorgt hier voor de juiste codering van de UTF-8-strings die uit de database worden geretourneerd. Er is (normaal gesproken) geen <![CDATA[...]]>
nodig hier niet langer. Zoals je je kunt voorstellen, heb je waarschijnlijk iets erin gestopt dat je XML-codering heeft verbroken.
Ook voor de database-interactie is het grootste deel van je code ook niet nodig, je kunt gewoon de rijen herhalen, als er geen rijen zijn, zou er geen iteratie zijn. Dit wordt normaal gesproken het best uitgedrukt met een Iterator
de foreach
taalconstructie kan werken op die wordt geleverd door moderne database-interfaces. Technisch gezien kun je $rows
replace vervangen hier met veel andere dingen, zoals een iterator die meerdere tabellen na elkaar doorloopt.
Bovendien bespaart het gebruik van de uitzonderingsfoutmodus u cheques te plaatsen en die
is overal in je codebase.
Een voorbeeldige output is:
<?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>
Als je dan nog steeds CDATA-elementen moet maken, werkt het op dezelfde manier (ik laat hier slechts een deel van het script zien, dat slechts een kleine wijziging bevat door CDATA-secties toe te voegen in plaats van een onderliggende waarde):
### 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))
;
}
}
Ook hier, DOMDocument
zorgt voor de juiste codering van de CDATA-sectie. Iets dat je waarschijnlijk niet hebt gedaan.
Mogelijke problemen die u nog steeds kunt tegenkomen, zijn met tabel- of rijnamen die ongeldige XML-namen
. Maar dan DOMDocument
zal het u daadwerkelijk vertellen, zodat u het weet tijdens het genereren van de XML, niet alleen achteraf met een coderingsfout.