Làm cách nào để bạn nhúng dữ liệu nhị phân vào XML?


107

Tôi có hai ứng dụng được viết bằng Java giao tiếp với nhau bằng các thông điệp XML qua mạng. Tôi đang sử dụng trình phân tích cú pháp SAX ở đầu nhận để lấy lại dữ liệu từ các thư. Một trong những yêu cầu là nhúng dữ liệu nhị phân vào thông điệp XML, nhưng SAX không thích điều này. Có ai biết cách để làm điều này không?

CẬP NHẬT: Tôi đã nhận được điều này làm việc với lớp Base64 từ thư viện codec apache commons , trong trường hợp bất kỳ ai khác đang thử điều gì đó tương tự.

Câu trả lời:



209

XML rất linh hoạt ...

<DATA>
  <BINARY>
    <BIT index="0">0</BIT>
    <BIT index="1">0</BIT>
    <BIT index="2">1</BIT>
    ...
    <BIT index="n">1</BIT>
  </BINARY>
</DATA>

XML giống như bạo lực - Nếu nó không giải quyết được vấn đề của bạn, nghĩa là bạn đang sử dụng nó không đủ.

BIÊN TẬP:

BTW: Base64 + CDATA có lẽ là giải pháp tốt nhất

(EDIT2:
Ai upmod cho tôi, hãy cũng upmod câu trả lời thực sự. Chúng tôi không muốn bất kỳ linh hồn tội nghiệp nào đến đây và thực sự thực hiện phương pháp của tôi vì nó được xếp hạng cao nhất trên SO, phải không?)


9
Đây chẳng khác gì một cách sử dụng XML hoàn toàn đáng hổ thẹn nếu bạn nghiêm túc. Và nếu bạn không phải, làm thế nào những người mới bắt đầu không viết-trình-độ-cao-cấp-thấp có thể biết được?
TheFlash 02/02/09

1
Tôi nghĩ nó buồn cười. Nhưng có, một lần nữa, sử dụng kiểu dữ liệu base64 thực tế là cách để đi. CData quá chung chung.
Omniwombat,

4
Tôi không nghĩ rằng nó đủ mô tả - có lẽ người ta nên sử dụng 'BINARYDIGIT' hơn là từ thu gọn 'BIT'? ;-)
Lee Atkinson

Chà. Điều này sẽ làm cho tệp phạm vi kilobyte trung bình lớn hơn khoảng 230 lần :)
Nyerguds

36
Ôi vì lợi ích của bạn. Đây là một trò đùa. Tôi đã làm gì:?! Thedailywtf.com/Articles/The-HumanReadable-Encryption-Key.aspx
Mo.

26

Base64 thực sự là câu trả lời đúng nhưng CDATA thì không, về cơ bản điều đó nói: "đây có thể là bất cứ thứ gì", tuy nhiên nó không phải là bất cứ thứ gì, nó phải là dữ liệu nhị phân được mã hóa Base64. Lược đồ XML xác định hệ nhị phân Cơ sở 64 như một kiểu dữ liệu nguyên thủy mà bạn có thể sử dụng trong xsd của mình.


2
Điểm bổ sung cho việc đề cập đến xs:base64Binarykiểu dữ liệu, đó là kiểu phù hợp để sử dụng.
Christopher Schultz

14

Tôi đã gặp vấn đề này chỉ tuần trước. Tôi đã phải tuần tự hóa một tệp PDF và gửi nó, bên trong một tệp XML, đến một máy chủ.

Nếu đang sử dụng .NET, bạn có thể chuyển đổi tệp nhị phân trực tiếp thành chuỗi base64 và gắn nó vào bên trong một phần tử XML.

string base64 = Convert.ToBase64String(File.ReadAllBytes(fileName));

Hoặc, có một phương thức được tích hợp ngay trong đối tượng XmlWriter. Trong trường hợp cụ thể của tôi, tôi phải bao gồm không gian tên kiểu dữ liệu của Microsoft:

StringBuilder sb = new StringBuilder();
System.Xml.XmlWriter xw = XmlWriter.Create(sb);
xw.WriteStartElement("doc");
xw.WriteStartElement("serialized_binary");
xw.WriteAttributeString("types", "dt", "urn:schemas-microsoft-com:datatypes", "bin.base64");
byte[] b = File.ReadAllBytes(fileName);
xw.WriteBase64(b, 0, b.Length);
xw.WriteEndElement();
xw.WriteEndElement();
string abc = sb.ToString();

Chuỗi abc trông giống như sau:

<?xml version="1.0" encoding="utf-16"?>
<doc>
    <serialized_binary types:dt="bin.base64" xmlns:types="urn:schemas-microsoft-com:datatypes">
        JVBERi0xLjMKJaqrrK0KNCAwIG9iago8PCAvVHlwZSAvSW5mbw...(plus lots more)
    </serialized_binary>
</doc>

câu trả lời hay nhất vì tôi có thể sao chép / dán Convert.ToBase64 Chuỗi từ nó
Eldritch Conundrum


5

Thử mã hóa / giải mã Base64 dữ liệu nhị phân của bạn. Cũng xem xét các phần CDATA


4

Có thể mã hóa chúng thành một tập hợp đã biết - một cái gì đó như cơ số 64 là một lựa chọn phổ biến.



4

Chi phí Base64 là 33%.

BaseXML cho chi phí XML1.0 chỉ là 20% . Nhưng nó không phải là một tiêu chuẩn và chỉ có một triển khai C. Hãy kiểm tra nếu bạn lo lắng về kích thước dữ liệu. Lưu ý rằng tuy nhiên, các trình duyệt có xu hướng thực hiện nén để nó ít cần thiết hơn.

Tôi đã phát triển nó sau cuộc thảo luận trong chủ đề này: Mã hóa dữ liệu nhị phân trong XML: các lựa chọn thay thế cho base64 .


4

Mặc dù các câu trả lời khác hầu hết đều ổn, bạn có thể thử một phương pháp mã hóa khác, tiết kiệm không gian hơn, như yEnc. ( liên kết yEnc wikipedia ) Với yEnc cũng có được khả năng tổng kiểm tra ngay "ra khỏi hộp". Đọc và liên kết bên dưới. Tất nhiên, vì XML không có kiểu yEnc gốc nên lược đồ XML của bạn nên được cập nhật để mô tả đúng nút được mã hóa.

Lý do : Do các chiến lược mã hóa base64 / 63, uuencode et al. mã hóa làm tăng lượng dữ liệu (tổng chi phí) bạn cần lưu trữ và chuyển lên khoảng 40% (so với 1-2% của yEnc). Tùy thuộc vào những gì bạn đang mã hóa, chi phí 40% có thể là / trở thành một vấn đề.


yEnc - Wikipedia tóm tắt: https://en.wikipedia.org/wiki/YEnc yEnc là một lược đồ mã hóa nhị phân thành văn bản để chuyển các tệp nhị phân trong thư trên Usenet hoặc qua e-mail. ... Một lợi thế bổ sung của yEnc so với các phương pháp mã hóa trước đó, chẳng hạn như uuencode và Base64, là bao gồm tổng kiểm tra CRC để xác minh rằng tệp được giải mã đã được phân phối nguyên vẹn. Các bác sĩ cho biết:


2
@Jamine, vậy bạn có cách thay thế nào khác không?
Săn

Jamie, đây có thể là một câu trả lời phù hợp với một chút công việc. Tôi đã xóa -1 của mình và sẽ +1 nếu bạn cố gắng ... gắn cờ cho tôi nếu bạn theo dõi.
Paul Sasik

Jamie, không. Tôi đã cập nhật câu trả lời của bạn và +1, hy vọng với thông tin mà bạn muốn truyền đạt ban đầu. Hãy xem qua và có thể cập nhật khi bạn thấy phù hợp. (Tôi đã không hoạt động trên SO một thời gian. Thật vui khi nghiên cứu và chỉnh sửa câu trả lời. Tôi đã +1 vì trong suốt quá trình đó, tôi đã học được một số điều mới và đó là tất cả những gì về ...? Chúc mừng.)
Paul Sasik

escapeless có thể là một thay thế cho yEnc khi dự đoán / cố định trên cao là rất quan trọng.
Ivan Kosarev

2

Bạn cũng có thể Uuencode cho dữ liệu nhị phân ban đầu. Định dạng này cũ hơn một chút nhưng nó hoạt động tương tự như mã hóa base63.


* mã hóa base63
luckydonald

0

Nếu bạn có quyền kiểm soát định dạng XML, bạn nên giải quyết vấn đề từ trong ra ngoài. Thay vì đính kèm XML nhị phân, bạn nên nghĩ về cách bao bọc một tài liệu có nhiều phần, một trong số đó chứa XML.

Giải pháp truyền thống cho điều này là một kho lưu trữ (ví dụ: tar). Nhưng nếu bạn muốn giữ tài liệu kèm theo của mình ở định dạng dựa trên văn bản hoặc nếu bạn không có quyền truy cập vào thư viện lưu trữ tệp, thì cũng có một lược đồ chuẩn hóa được sử dụng nhiều trong email và HTTP là nhiều phần / * MIME với Nội dung-Chuyển-Mã hoá: nhị phân .

Ví dụ: nếu máy chủ của bạn giao tiếp qua HTTP và bạn muốn gửi tài liệu nhiều phần, tài liệu chính là tài liệu XML đề cập đến dữ liệu nhị phân, giao tiếp HTTP có thể trông giống như sau:

POST / HTTP/1.1
Content-Type: multipart/related; boundary="qd43hdi34udh34id344"
... other headers elided ...

--qd43hdi34udh34id344
Content-Type: application/xml

<myxml>
    <data href="cid:data.bin"/>
</myxml>
--qd43hdi34udh34id344
Content-Id: <data.bin>
Content-type: application/octet-stream
Content-Transfer-Encoding: binary

... binary data ...
--qd43hdi34udh34id344--

Như trong ví dụ trên, XML tham chiếu đến dữ liệu nhị phân trong nhiều phần bao quanh bằng cách sử dụng cidlược đồ URI là mã định danh cho tiêu đề Content-Id. Phần đầu của lược đồ này sẽ chỉ là tiêu đề MIME. Một lược đồ tương tự cũng có thể được sử dụng cho phản hồi HTTP. Tất nhiên trong giao thức HTTP, bạn cũng có tùy chọn gửi một tài liệu nhiều phần thành yêu cầu / phản hồi riêng biệt.

Nếu bạn muốn tránh gói dữ liệu của mình thành nhiều phần, hãy sử dụng URI dữ liệu:

<myxml>
    <data href="data:application/something;charset=utf-8;base64,dGVzdGRhdGE="/>
</myxml>

Nhưng điều này có chi phí base64.

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.