Câu hỏi của bạn thực sự rất rộng, câu trả lời tốt nhất mà tôi có thể đưa ra là bạn nên sử dụng một số thư viện hiện có để mã hóa XML thay vì viết thư viện của riêng bạn (vì bạn rõ ràng đã thất bại với công việc do đó lỗi mã hóa XML được báo cáo bởi cơ quan XML).
Sử dụng một thư viện hiện có cũng sẽ cho phép bạn chỉ ra các vấn đề sớm hơn. Ví dụ. đối với mã sau, hãy đảm bảo tất cả những gì bạn lấy lại được từ cơ sở dữ liệu của mình là các chuỗi được mã hóa UTF-8.
Ngoài ra, việc sử dụng một lớp máy khách cơ sở dữ liệu hiện đại hơn cũng sẽ giúp bạn rất nhiều chỉ cần viết ra mã. Đây là một ví dụ với PDO
và 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();
Xem DomDocument
đó đang quan tâm đến việc mã hóa đúng các chuỗi UTF-8 được trả về từ cơ sở dữ liệu ở đây. (Thông thường) không cần <![CDATA[...]]>
ở đây nữa. Như bạn có thể tưởng tượng, bạn có thể đặt thứ gì đó vào đó làm hỏng mã hóa XML của bạn.
Ngoài ra đối với tương tác cơ sở dữ liệu, hầu hết mã của bạn cũng không cần thiết, bạn chỉ có thể lặp lại các hàng, nếu không có hàng nào, sẽ không có lặp lại. Điều này thường được thể hiện tốt nhất với Iterator
foreach
cấu trúc ngôn ngữ có thể hoạt động trên đó được cung cấp bởi các giao diện cơ sở dữ liệu hiện đại. Về mặt kỹ thuật, bạn có thể thay thế $rows
ở đây với nhiều thứ khác, chẳng hạn như một trình lặp lần lượt lướt qua nhiều bảng.
Ngoài ra, việc sử dụng chế độ lỗi ngoại lệ sẽ giúp bạn kiểm tra và die
trên toàn bộ cơ sở mã của bạn.
Đầu ra mẫu là:
Giá trị<?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>
Nếu sau đó bạn vẫn cần tạo các phần tử CDATA, thì nó hoạt động tương tự (tôi chỉ hiển thị một phần của tập lệnh ở đây, chỉ chứa một sửa đổi nhỏ thêm các phần CDATA thay vì giá trị con):
### 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))
;
}
}
Ở đây cũng vậy, DOMDocument
chú ý đến việc mã hóa đúng phần CDATA. Điều gì đó có thể là bạn đã không làm.
Các vấn đề tiềm ẩn mà bạn vẫn có thể gặp phải là với tên bảng hoặc hàng tên XML không hợp lệ
. Nhưng sau đó DOMDocument
sẽ thực sự cho bạn biết để bạn biết trong khi tạo XML, không chỉ sau đó với lỗi mã hóa.