Lỗi cú pháp XML thường gặp và cách sửa từng lỗi

Mười hai lỗi XML khiến bộ phân tích dừng lại, mỗi lỗi có ví dụ, vị trí được báo và cách sửa, cùng lý do không được định dạng lại nội dung hỗn hợp.

Trong bài này

HTML bỏ qua gần như mọi thứ: thiếu thẻ đóng, thuộc tính không có ngoặc kép, dấu & lạc chỗ. XML thì không bỏ qua gì cả. Đặc tả quy định khi bộ phân tích gặp lỗi về cú pháp (well-formedness), nó phải dừng lại và báo lỗi, không được đoán. Sự nghiêm ngặt đó là lý do một feed XML, một sitemap, một tệp hoá đơn hay một layout Android có thể hỏng chỉ vì một ký tự, và thông báo lỗi thường là manh mối duy nhất bạn có.

Bài này đi qua những lỗi hay gặp nhất, mỗi lỗi kèm một ví dụ hỏng tối giản, thông báo mà công cụ định dạng và kiểm tra XML đưa ra, và cách sửa. Số dòng và số cột đếm từ 1.

Đúng cú pháp và hợp lệ theo lược đồ

Đúng cú pháp (well-formed) nghĩa là văn bản tuân theo cú pháp của chính XML: một phần tử gốc, mọi thẻ đều được đóng và lồng đúng thứ tự, thuộc tính có ngoặc kép, ký tự đặc biệt được thoát. Mọi bộ phân tích XML đều kiểm tra điều này.

Hợp lệ (valid) nghĩa là tài liệu còn tuân theo một lược đồ (DTD, XSD hoặc RelaxNG) quy định phần tử nào được xuất hiện ở đâu. Một tệp có thể đúng cú pháp hoàn toàn mà vẫn không hợp lệ, ví dụ sitemap thiếu <loc>. Các lỗi dưới đây đều là lỗi cú pháp: chưa sửa xong thì không công đoạn nào phía sau chịu nhìn tới tài liệu của bạn.

Những ký tự phải được thoát

1. Dấu `&` đứng trơ trọi. <name>Bread & Butter</name> lỗi ở dòng 1, cột 19, đúng dấu &. Trong XML, & luôn mở đầu một tham chiếu như &amp;. Hãy viết Bread &amp; Butter. Đây là lỗi phổ biến nhất trong XML sửa tay hoặc sinh tự động, thường đến từ tên sản phẩm hoặc URL có chuỗi truy vấn: ?a=1&b=2 phải viết thành ?a=1&amp;b=2 bên trong XML.

2. Tên thực thể của HTML. <p>Price&nbsp;10</p> lỗi ở cột 9 tại &nbsp;. XML chỉ định nghĩa sẵn năm thực thể có tên: &lt;, &gt;, &amp;, &quot; và &apos;. Mọi thứ khác phải dùng tham chiếu số (&#160; cho dấu cách không ngắt dòng) hoặc chính ký tự đó ở dạng UTF-8. Công cụ mã hoá thực thể HTML chuyển đổi giữa các dạng; xem bài thực thể HTML, UTF-8 và thoát ký tự để biết khi nào cần chúng.

3. Dấu nhỏ hơn trong thuộc tính. <rule test="a < b"/> lỗi ở cột 15. Dấu < không bao giờ được phép trong giá trị thuộc tính; hãy viết &lt;. Còn dấu > thì được phép, điều khiến nhiều người bất ngờ theo chiều ngược lại.

4. Ký tự điều khiển. <a>bell theo sau là ký tự U+0007 bị báo "Ký tự U+0007 không được phép trong XML". XML 1.0 cấm hầu hết ký tự điều khiển dưới U+0020 (trừ tab, xuống dòng và về đầu dòng), kể cả khi viết dạng &#7;. Chúng thường lọt vào từ văn bản dán ra từ cửa sổ dòng lệnh hoặc một trường cơ sở dữ liệu. Hãy loại bỏ chúng trước khi sinh XML.

Lỗi cấu trúc

5. Hai phần tử gốc. Tệp chứa <item>1</item> rồi tới <item>2</item> ở dòng 2 sẽ lỗi ở dòng 2, cột 1: "Phần tử gốc thứ hai bắt đầu ở đây." Tài liệu XML có đúng một phần tử gốc. Hãy bọc các mục lại: <items>…</items>. Lỗi này hay xảy ra khi ai đó nối hai tệp XML xuất ra với nhau.

6. Thẻ đóng sai thứ tự hoặc chồng chéo. <order><line><qty>2</line></qty></order> lỗi ở cột 20: "Thẻ đóng này là </line> nhưng phần tử đang mở là <qty>." Các phần tử phải đóng theo thứ tự ngược với lúc mở. Bộ phân tích HTML âm thầm sửa <b><i>x</b></i>; bộ phân tích XML thì từ chối.

7. Chữ hoa chữ thường. <Item></item> lỗi theo cùng cách. Tên trong XML phân biệt hoa thường, nên Item và item là hai phần tử khác nhau.

8. Thuộc tính không có ngoặc kép. <item id=42/> lỗi ở cột 10. Mọi giá trị thuộc tính đều cần ngoặc đơn hoặc ngoặc kép: id="42".

9. Thuộc tính lặp lại. <item id="1" id="2"/> lỗi ở id thứ hai, cột 14. Mỗi thuộc tính chỉ được xuất hiện một lần trên một phần tử.

Lỗi vị trí và khai báo

10. Có thứ gì đó trước khai báo XML. Tệp bắt đầu bằng một dòng trống rồi mới tới <?xml version="1.0"?> lỗi ở dòng 2, cột 1: khai báo phải là thứ đầu tiên trong tệp. Thủ phạm thường là một template in ra dấu xuống dòng trước nó, hoặc tệp PHP có khoảng trắng trước <?php. Thứ duy nhất được phép đứng trước là dấu thứ tự byte (BOM), và công cụ bỏ nó đi trước khi kiểm tra.

11. Tiền tố không gian tên chưa khai báo. <g:price>10</g:price> lỗi vì tiền tố g: chưa được khai báo. Trong feed Google Merchant, phần tử gốc phải có xmlns:g="http://base.google.com/ns/1.0". Một bộ phân tích XML 1.0 thuần không xét không gian tên sẽ chấp nhận cái tên này; mọi chương trình có xét không gian tên thì không, vì thế công cụ kiểm tra.

12. Hai dấu gạch nối trong chú thích. <!-- a -- b --> lỗi: chú thích không được chứa -- hoặc kết thúc bằng -. Chú thích hoá một khối vốn đã có chú thích bên trong, hoặc chứa tuỳ chọn dòng lệnh như --verbose, sẽ gây ra lỗi này.

Những gì bộ định dạng không được thay đổi

Khi tài liệu đã phân tích được, việc định dạng cho đẹp trông có vẻ vô hại, nhưng khoảng trắng trong XML có thể là dữ liệu. Lấy ví dụ:

<order id="7"><line sku="A1" qty="2"/><note>Leave at <b>door</b></note></order>

Công cụ định dạng thành:

<order id="7">
  <line sku="A1" qty="2"/>
  <note>Leave at <b>door</b></note>
</order>

order chỉ chứa phần tử, nên thêm xuống dòng và thụt lề giữa các con của nó là an toàn. note chứa văn bản trộn với phần tử (nội dung hỗn hợp), nên được giữ đúng như cũ. Thụt lề lại nó sẽ chèn xuống dòng và dấu cách vào câu "Leave at door", và một số chương trình sẽ in chúng ra. Thứ tự thuộc tính và kiểu ngoặc cũng được giữ nguyên, vì người đọc bản so sánh thay đổi muốn chúng đứng yên; sắp xếp thuộc tính là một tuỳ chọn, mặc định tắt.

Những lỗi thường gặp

  1. Tạo XML bằng cách nối chuỗi. Hãy dùng thư viện có thoát ký tự, hoặc tự thoát & < > " ' trong mọi giá trị.
  2. Sửa đúng vị trí được báo trong khi nguyên nhân nằm ở phía trước. Thẻ đóng sai được báo ở chỗ bộ phân tích phát hiện ra, có thể cách thẻ bạn quên đóng rất nhiều dòng. Hãy nhìn phần tử đang mở được nêu tên trong thông báo.
  3. Lưu tệp bằng bảng mã cũ trong khi khai báo ghi UTF-8. Chữ tiếng Việt có dấu khi đó làm hỏng việc phân tích hoặc biến thành ký tự rác.
  4. Coi việc "mở được trong trình duyệt" là bằng chứng tệp đúng. Trình duyệt chỉ kiểm tra cú pháp; trình đọc feed hay cổng hoá đơn điện tử còn kiểm tra theo lược đồ.

Hãy dán bất kỳ tài liệu nào vào công cụ định dạng XML: nó sẽ định dạng, hoặc chỉ ra lỗi đầu tiên kèm dòng, cột và dấu mũ ngay dưới ký tự lỗi, tất cả trong trình duyệt của bạn.

Công cụ được nhắc trong bài

Về trang blog