Vaše otázka je opravdu široká, nejlepší odpověď, kterou mohu dát, je, že byste měli ke kódování XML použít nějakou existující knihovnu místo psaní své vlastní (protože se vám zjevně nedaří s úlohou, proto chyba kódování XML hlášená spotřebitelem XML).
Použití existující knihovny by vám také umožnilo upozornit na problémy dříve. Např. pro následující kód zajistěte, aby vše, co získáte zpět z databáze, jsou řetězce zakódované v UTF-8.
Také použití modernější třídy databázového klienta vám také pomůže velmi jednoduše zapsat kód. Zde je příklad s PDO
a 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();
Podívejte se na tento DomDocument
se zde stará o správné kódování řetězců UTF-8, které jsou vráceny z databáze. <![CDATA[...]]>
(normálně) není potřeba tady už déle. Jak si dokážete představit, pravděpodobně jste tam vložili něco, co narušilo vaše kódování XML.
Také pro interakci s databází není nutná ani většina vašeho kódu, můžete jen iterovat přes řádky, pokud žádné řádky nejsou, žádná iterace by nebyla. To se obvykle nejlépe vyjadřuje pomocí Iterator
foreach
může fungovat jazykový konstrukt, na kterém je poskytováno moderní databázová rozhraní. Technicky můžete nahradit $rows
zde s mnoha dalšími věcmi, jako je iterátor, který prochází více tabulkami jednu po druhé.
Navíc použití režimu chyb výjimek vás ušetří na umisťování kontrol a die
je po celé vaší kódové základně.
Příkladný výstup je:
<?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>
Pokud pak stále potřebujete vytvořit prvky CDATA, funguje to podobně (zde uvádím pouze část skriptu, která obsahuje pouze drobnou úpravu přidáním částí CDATA namísto podřízené hodnoty):
### 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))
;
}
}
Zde také DOMDocument
se stará o správné kódování sekce CDATA. Něco, co jste pravděpodobně neudělali.
Potenciální problémy, se kterými se stále můžete setkat, jsou s názvy tabulek nebo řádků, které jsou neplatné názvy XML
. Ale pak DOMDocument
ve skutečnosti vám to řekne, abyste věděli při generování XML, nejen poté s chybou kódování.