Tệp XML hợp lệ có yêu cầu khai báo XML không?


122

Tôi đang phân tích cú pháp một tệp XML bằng Sax Parser của Xerces.
<?xml version="1.0" encoding="UTF-8"?>cần khai báo XML không?


3
Có sự khác biệt giữa tài liệu hợp lệ và tài liệu có hình thức tốt. Ý bạn là gì?
Felix Kling

Tôi nhận được lỗi prolog / mã hóa utf-8 không hợp lệ. Sau đó, tôi tìm thấy BOM trong tệp XML mà người dùng mở tệp bằng notepad (tôi không thể tránh điều này). tôi không chắc mình đang đề cập đến một tài liệu hợp lệ hoặc có hình thức tốt. Chỉ cần tránh các lỗi đó là lý do tại sao tôi đang tạo một hàm xóa tất cả các byte trước "<". Mà tôi cần đảm bảo rằng khai báo tiêu đề xml là bắt buộc. Bạn nghĩ gì chàng trai?
eros

Có lớp java nào xóa BOM không? hay vài byte từ tệp xml? từ InputStream. Tôi đang nghĩ đến phương pháp bỏ qua từ FilterInputStream & PushbackInputStream nhưng không có ý tưởng về cách sử dụng nó.
eros

@eros: " Tôi không chắc mình đang đề cập đến tài liệu hợp lệ hoặc được định dạng tốt " Xem XML hợp lệ so với XML hợp lệ để có giải thích ngắn gọn về sự khác biệt.
kjhughes

Câu trả lời:


184

Trong XML 1.0, Tuyên bố XMLtùy chọn . Xem phần 2.8 của Khuyến nghị XML 1.0 , trong đó nó nói rằng nó "nên" được sử dụng - có nghĩa là nó được khuyến nghị, nhưng không bắt buộc. Tuy nhiên, trong XML 1.1, việc khai báo là bắt buộc . Xem phần 2.8 của Khuyến nghị XML 1.1 , trong đó nó nói "PHẢI" được sử dụng. Nó thậm chí còn tuyên bố rằng nếu không có khai báo, điều đó tự động ngụ ý rằng tài liệu là một tài liệu XML 1.0.

Lưu ý rằng trong một khai báo XML sự encodingstandalonecả hai đều không bắt buộc. Chỉ có versionlà bắt buộc. Ngoài ra, đây không phải là các thuộc tính, vì vậy nếu chúng có mặt thì chúng phải theo thứ tự versionđó:, theo sau là bất kỳ encoding, theo sau là bất kỳ standalone.

<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" standalone="yes"?>
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>

Nếu bạn không chỉ định mã hóa theo cách này, trình phân tích cú pháp XML sẽ cố gắng đoán mã hóa nào đang được sử dụng. Khuyến nghị XML 1.0 mô tả một cách khả thi có thể tự động phát hiện mã hóa ký tự . Trong thực tế, điều này không có nhiều vấn đề nếu đầu vào được mã hóa là UTF-8, UTF-16 hoặc US-ASCII. Tính năng tự động phát hiện không hoạt động khi nó gặp các mã hóa 8 bit sử dụng các ký tự bên ngoài phạm vi US-ASCII (ví dụ: ISO 8859-1) - hãy tránh tạo các mã này nếu bạn có thể.

Dấu standalonecho biết liệu tài liệu XML có thể được xử lý chính xác mà không cần DTD hay không. Mọi người ít sử dụng nó. Ngày nay, thật tệ khi thiết kế một định dạng XML thiếu thông tin mà không có DTD của nó.

Cập nhật:

Lỗi "lỗi prolog / mã hóa utf-8 không hợp lệ" chỉ ra rằng dữ liệu thực tế mà trình phân tích cú pháp tìm thấy bên trong tệp không khớp với kiểu mã hóa mà khai báo XML cho biết. Hoặc trong một số trường hợp, dữ liệu bên trong tệp không khớp với mã hóa được phát hiện tự động.

Vì tệp của bạn chứa dấu thứ tự byte (BOM) nên tệp phải ở dạng mã hóa UTF-16. Tôi nghi ngờ rằng tuyên bố của bạn cho biết <?xml version="1.0" encoding="UTF-8"?>rõ ràng là không chính xác khi tệp đã được NotePad thay đổi thành UTF-16. Giải pháp đơn giản là loại bỏencoding và đơn giản nói <?xml version="1.0"?>. Bạn cũng có thể chỉnh sửa nó để nói encoding="UTF-16"nhưng điều đó sẽ sai đối với tệp gốc (không có trong UTF-16) hoặc nếu tệp bằng cách nào đó được thay đổi trở lại UTF-8 hoặc một số mã hóa khác.

Đừng bận tâm đến việc loại bỏ BOM - đó không phải là nguyên nhân của vấn đề. Sử dụng NotePad hoặc WordPad để chỉnh sửa XML là một vấn đề thực sự!


Câu hỏi của tôi đã được trả lời nhưng câu hỏi tiếp theo của tôi thì không. Tôi có cần tạo một câu hỏi khác cho điều đó không? hoặc vui lòng thêm nó ở đây.
eros

5
BOM có thể là nguyên nhân của vấn đề. Một số trình phân tích cú pháp XML cũ hơn sẽ không chấp nhận BOM khi bắt đầu tài liệu UTF-8 (nó được thiết kế cho UTF-16 và chỉ được chấp nhận với UTF-8 sau này). Nhưng sẽ không thành vấn đề nếu bạn đang sử dụng phiên bản Xerces gần đây.
Michael Kay

Cũng lưu ý rằng trong hộp thoại "Lưu dưới dạng" trong notepad, bạn có thể chọn kiểu mã hóa để lưu XML của mình dưới dạng. Nếu bạn muốn xóa BOM, chỉ cần lưu dưới dạng "ASCII" (giả sử bạn không sử dụng bất kỳ ký tự Unicode nào). Đối với 127 ký tự thấp hơn, ASCII và UTF-8 giống hệt nhau.
BrainSlugs83

8

Khai báo Xml là tùy chọn để xml của bạn được định dạng tốt mà không cần nó. Nhưng chúng tôi khuyên bạn nên sử dụng nó để người phân tích cú pháp không đưa ra các giả định sai, cụ thể là về cách mã hóa được sử dụng.


3
Tôi có phải là người duy nhất thấy kỳ lạ khi bạn nói với bộ phân tích cú pháp XML nên sử dụng cách mã hóa nào sau khi họ đã bắt đầu giải mã tài liệu của bạn không? Ý tôi là rõ ràng, nếu nó có thể phân tích cú pháp thẻ đó và hiểu những gì nó nói, thì nó đã tìm ra mã hóa chính xác. Tôi không thể nghĩ ra bất kỳ cách sử dụng hợp pháp nào cho thuộc tính mã hóa.
BrainSlugs83

2
@ BrainSlugs83 Không có BOM, mã hóa được chỉ định là 8 bit. Vì vậy, ASCII hoặc UTF-8 hoặc bất kỳ mã hóa quốc gia 8 bit cũ nào trong số chúng. Khai báo XML là tất cả 8 bit nửa dưới, bằng nhau trong số tất cả các mã hóa đó và truyền tải đủ thông tin để chọn nửa trên. Không phải là tốt nhất về thiết kế, nhưng vẫn tốt hơn là đoán giữa CP1241 và CP866 như thường thấy đối với các tệp văn bản của chúng ngày xưa.
Eugene Ryabtsev

Nhưng lẽ ra họ phải làm sạch và nói rằng XML là UTF-8 - phần cuối của câu chuyện.
Lothar

3

Nó chỉ bắt buộc nếu bạn không sử dụng các giá trị mặc định cho versionencoding(bạn đang ở trong ví dụ đó).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.