आप XML में बाइनरी डेटा कैसे एम्बेड करते हैं?


107

मेरे पास जावा में लिखे गए दो एप्लिकेशन हैं जो नेटवर्क पर XML संदेशों का उपयोग करते हुए एक-दूसरे के साथ संवाद करते हैं। मैं संदेश प्राप्त करने के लिए डेटा को वापस लाने के लिए प्राप्त करने के अंत में SAX पार्सर का उपयोग कर रहा हूं। आवश्यकताओं में से एक XML संदेश में बाइनरी डेटा एम्बेड करना है, लेकिन SAX को यह पसंद नहीं है। क्या किसी को भी यह करना आता है?

अद्यतन करें: मुझे यह अपाचे कॉमन्स कोडेक लाइब्रेरी से बेस 64 वर्ग के साथ काम कर रहा है , अगर कोई और भी कुछ इसी तरह की कोशिश कर रहा है।

जवाबों:


216

आप आधार संख्या का उपयोग करके बाइनरी डेटा को एन्कोड कर सकते हैं और इसे बेस 64 तत्व में डाल सकते हैं; नीचे दिए गए लेख विषय पर बहुत अच्छा है।

XML दस्तावेज़ों में बाइनरी डेटा को संभालना


209

XML इतनी बहुमुखी है ...

<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 हिंसा की तरह है - यदि यह आपकी समस्या को हल नहीं करता है, तो आप इसका पर्याप्त उपयोग नहीं कर रहे हैं।

संपादित करें:

BTW: Base64 + CDATA शायद सबसे अच्छा समाधान है

(EDIT2:
जो कोई भी मुझे उखाड़ फेंकता है, कृपया वास्तविक उत्तर को भी उखाड़ फेंकें। हम नहीं चाहते कि कोई गरीब आत्मा यहां आए और वास्तव में मेरी विधि को लागू करे, क्योंकि यह SO पर सर्वोच्च स्थान पर था, है ना?)


9
यदि आप गंभीर हैं तो यह XML के पूरी तरह से अपमानजनक उपयोग से कम नहीं है। और यदि आप नहीं हैं, तो शुरुआती लोग जो उच्च-स्तरीय-थिंक-कम-स्तरीय नहीं लिखते हैं, वे कैसे जानते हैं?
फलैश

1
मुझे लगता है कि यह मजाकिया है। लेकिन हाँ, एक बार फिर, वास्तविक बेस 64 डेटाटाइप का उपयोग करने का तरीका है। CData बहुत सामान्य है।
ओमनीवॉम्बैट

4
मुझे नहीं लगता कि यह पर्याप्त रूप से वर्णनात्मक है - शायद किसी को 'BITARYDIGIT' का उपयोग संकुचन 'BIT' के बजाय करना चाहिए? ;-)
ली एटकिंसन

वाह। यह औसत किलोबाइट-श्रेणी फ़ाइल को 230 गुना बड़ा बना देगा :)
Nyerguds

36
ओह च के लिए *** s खातिर। यह एक मजाक था। मैंने क्या किया ?: Thedailywtf.com/Articles/The-HumanReadable-Enc एन्क्रिप्शन-Key.aspx
Mo.

26

Base64 वास्तव में सही उत्तर है, लेकिन CDATA नहीं है, यह मूल रूप से कह रहा है: "यह कुछ भी हो सकता है", हालांकि यह सिर्फ कुछ भी नहीं होना चाहिए , यह Base64 एन्कोडेड बाइनरी डेटा होना चाहिए। XML स्कीमा बेस 64 बाइनरी को एक आदिम डेटाटाइप के रूप में परिभाषित करता है जिसे आप अपने xsd में उपयोग कर सकते हैं।


2
xs:base64Binaryडेटा प्रकार का उल्लेख करने के लिए अतिरिक्त बिंदु , जो उपयोग करने के लिए सही प्रकार है।
क्रिस्टोफर

14

मुझे यह समस्या पिछले हफ्ते ही हुई थी। मुझे एक पीडीएफ फाइल को सीरियल करना था और इसे एक XML फाइल के अंदर, एक सर्वर पर भेजना था।

यदि आप .NET का उपयोग कर रहे हैं, तो आप एक बाइनरी फ़ाइल को सीधे बेस 64 स्ट्रिंग में बदल सकते हैं और इसे एक्सएमएल तत्व के अंदर चिपका सकते हैं।

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

या, XmlWriter ऑब्जेक्ट में सही तरीके से निर्मित विधि है। मेरे विशेष मामले में, मुझे 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();

स्ट्रिंग एबीसी कुछ ऐसा दिखता है जो इस तरह दिखता है:

<?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>

सबसे अच्छा जवाब क्योंकि मैं इसे कॉपी / पेस्ट कर सकता हूं Convert.ToBase64String से
Eldritch Conundrum


5

अपने बाइनरी डेटा को बेस 64 एन्कोडिंग / डिकोड करने का प्रयास करें। CDATA अनुभाग भी देखें


4

शायद उन्हें एक ज्ञात सेट में सांकेतिक शब्दों में बदलना - कुछ आधार 64 की तरह एक लोकप्रिय विकल्प है।



4

बेस 64 ओवरहेड 33% है।

XML1.0 ओवरहेड के लिए बेसएक्सएमएल केवल 20% है । लेकिन यह एक मानक नहीं है और केवल एक सी कार्यान्वयन अभी तक है। यदि आप डेटा आकार से संबंधित हैं, तो इसे देखें। हालांकि ध्यान दें कि ब्राउज़र संपीड़न को लागू करने के लिए जाता है ताकि इसकी कम आवश्यकता हो।

मैंने इसे इस थ्रेड में चर्चा के बाद विकसित किया है: XML के भीतर द्विआधारी डेटा को एन्कोड करना: बेस 64 के लिए विकल्प


4

जबकि अन्य उत्तर ज्यादातर ठीक हैं, आप एक और, अधिक स्थान-कुशल, एन्कोडिंग विधि जैसे yEnc की कोशिश कर सकते हैं। ( yEnc विकिपीडिया लिंक ) yEnc के साथ चेकसम क्षमता भी सही है "बॉक्स से बाहर"। नीचे पढ़ें और लिंक बेशक, क्योंकि XML में एक देशी yEnc प्रकार नहीं है, आपके XML स्कीमा को एन्कोडेड नोड का ठीक से वर्णन करने के लिए अपडेट किया जाना चाहिए।

क्यों : एन्कोडिंग रणनीतियों के कारण base64 / 63, uuencode et al। एन्कोडिंग में डेटा की मात्रा बढ़ जाती है (ओवरहेड) आपको लगभग 40% (बनाम yEnc के 1-2%) द्वारा स्टोर और ट्रांसफर करने की आवश्यकता होती है। आप जो एन्कोडिंग कर रहे हैं, उसके आधार पर 40% ओवरहेड एक मुद्दा बन सकता है।


yEnc - विकिपीडिया सार: https://en.wikipedia.org/wiki/YEnc yEnc एक बाइनरी-टू-टेक्स्ट एन्कोडिंग योजना है जो यूज़नेट पर संदेशों में बाइनरी फ़ाइलों को स्थानांतरित करने के लिए या ई-मेल के माध्यम से है। ... uuencode और Base64 जैसे पिछले एन्कोडिंग विधियों पर yEnc का एक अतिरिक्त लाभ, यह सत्यापित करने के लिए एक CRC चेकसम का समावेश है कि डिकोड की गई फ़ाइल को बरकरार रखा गया है।


2
@Jamine तो क्या आपके पास कोई अन्य विकल्प है?
हंट

जेमी, यह एक सभ्य जवाब हो सकता है थोड़ा और काम दिया जाए। मैंने अपना -1 और विल +1 हटा दिया यदि आप इसे कुछ प्रयास देते हैं ... यदि आप अनुवर्ती कार्रवाई करते हैं तो मुझे चिह्नित करें।
पॉल शशिक

जेमी, एन / एम। मैंने आपके उत्तर को अपडेट किया, और + 1ed, उम्मीद है कि इस जानकारी के साथ कि आप मूल रूप से व्यक्त करने वाले थे। एक नज़र डालें और संभवत: अपडेट करें जैसे कि आप फिट दिखते हैं। (मैं कुछ समय के लिए SO पर सक्रिय नहीं रहा। यह शोध और एक उत्तर को संपादित करने के लिए मजेदार था। I + 1ed क्योंकि जिस तरह से मैंने कुछ नई चीजों को सीखा है और यही वह सब है ...? चीयर्स।)
पॉल ससिक

जब भविष्यवाचक / निश्चित ओवरहेड क्रिटिकल हो, तो escapeless yEnc का विकल्प हो सकता है।
इवान कोसारेव


0

यदि आपके पास XML प्रारूप पर नियंत्रण है, तो आपको समस्या को अंदर बाहर करना चाहिए। बाइनरी एक्सएमएल को संलग्न करने के बजाय आपको यह सोचना चाहिए कि एक दस्तावेज़ को कैसे संलग्न करना है जिसमें कई भाग हैं, जिनमें से एक में एक्सएमएल शामिल है।

इसका पारंपरिक समाधान एक संग्रह (जैसे टार) है। लेकिन अगर आप अपने संलग्न दस्तावेज़ को पाठ-आधारित प्रारूप में रखना चाहते हैं या यदि आपके पास फ़ाइल संग्रह पुस्तकालय में प्रवेश नहीं है, तो एक मानकीकृत योजना भी है जो ईमेल और HTTP में बहुत अधिक उपयोग की जाती है जो मल्टीपार्ट / * MIME के साथ है। सामग्री-अंतरण-एन्कोडिंग: बाइनरी

उदाहरण के लिए यदि आपके सर्वर HTTP के माध्यम से संवाद करते हैं और आप मल्टीपार्ट डॉक्यूमेंट भेजना चाहते हैं, तो प्राथमिक एक एक्सएमएल दस्तावेज है जो बाइनरी डेटा को संदर्भित करता है, एचटीटीपी संचार कुछ इस तरह दिख सकता है:

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--

जैसा कि ऊपर उदाहरण में, XML एक cidयूआरआई योजना का उपयोग करके मल्टीप्लेयर में बाइनरी डेटा को संदर्भित करता है जो सामग्री-आईडी हेडर के लिए एक पहचानकर्ता है। इस योजना का ओवरहेड सिर्फ MIME हेडर होगा। एक समान योजना का उपयोग HTTP प्रतिक्रिया के लिए भी किया जा सकता है। निश्चित रूप से HTTP प्रोटोकॉल में, आपके पास मल्टीपार्ट डॉक्यूमेंट को अलग-अलग अनुरोध / प्रतिक्रिया में भेजने का विकल्प भी है।

यदि आप अपने डेटा को मल्टीपार्ट में लपेटने से बचना चाहते हैं तो डेटा का उपयोग करना होगा URI:

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

लेकिन इसका बेस 64 ओवरहेड है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.