2008-08-21 13 views
95

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

अद्यतन: apache commons codec library से Base64 कक्षा के साथ यह काम कर रहा है, अगर कोई और कुछ ऐसा करने की कोशिश कर रहा है।

+3

प्रतिभा! मुझे इसकी ही खोज थी! –

उत्तर

192

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

Handling Binary Data in XML Documents

+0

देखभाल करें, कुछ फ़ायरवॉल (https-कनेक्शन) कभी-कभी ब्लॉक करते हैं जब "=" वर्ण मौजूद होता है। (स्ट्रिंग के कई एन्कोडिंग जैसे "kdiLKjdfdilfse =") – tObi

4

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

5

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

6

मैं आमतौर पर MIME Base64 या URL encoding साथ बाइनरी डेटा सांकेतिक शब्दों में बदलना।

190

एक्सएमएल तो बहुमुखी है ...

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

एक्सएमएल हिंसा तरह है - यह आपकी समस्या का समाधान नहीं होता है, तो आप इसके बारे में पर्याप्त उपयोग नहीं कर रहे।

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

BTW

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

(EDIT2:।
जो कोई भी मुझे upmods, यह भी असली जवाब upmod कृपया हम नहीं किसी भी गरीब आत्मा आना चाहते हैं यहाँ और वास्तव में मेरे तरीका लागू है क्योंकि यह उच्चतम पर एसओ, सही स्थान पर रहीं थी)

+0

मैंने अपने दोस्त को यह उद्धरण दोहराया, और हँसे जाने के बाद, उन्होंने कहा, "और अगर आपको निर्देशित किया गया तो यह दर्दनाक है" :) – kaybenleroll

+5

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

+1

जेरेमी ...एक युवा 23 वर्षीय लड़के के लिए आप बहुत गंभीर/शाब्दिक हैं ... आपने स्पष्ट रूप से उद्योग में काफी समय तक काम नहीं किया है यह देखने के लिए कि यह लाइनों के बीच बहादुर के लिए एक चेतावनीपूर्ण कहानी के साथ एक मनोरंजक उत्तर क्यों है। – Kev

22

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

+1

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

2

आप मूल बाइनरी डेटा भी Uuencode कर सकते हैं। यह प्रारूप थोड़ा पुराना है लेकिन यह बेस 63 एन्कोडिंग जैसा ही काम करता है।

3

कोई भी binary-to-text encoding चाल करेगा। मैं कुछ

<data encoding="yEnc> 
<![CDATA[ encoded binary data ]]> 
</data> 
9

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

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

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

या, XmlWriter ऑब्जेक्ट में सही तरीके से बनाया गया एक तरीका है।मेरी विशेष मामले में, मैं माइक्रोसॉफ्ट के डेटाप्रकार नाम स्थान में शामिल करने के लिए किया था:

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

यहाँ कैसे आगे बढ़ना का एक अच्छा उदाहरण है XEP-0239

पीएस: Mo's answer पढ़ने के लिए मत भूलना।

पीएस 2: एक्सईपी पर नोटिस अनुभाग पढ़ें।

2

बेस 64 एन्कोडिंग का उपयोग न करें क्योंकि यह कम से कम 40% तक स्टोर करने के लिए आवश्यक डेटा की मात्रा बढ़ाता है। इसके बजाय वाईएनएनसी जैसी अन्य एन्कोडिंग विधियों का उपयोग करें।

+1

@ जैमिन तो क्या आपके पास कोई अन्य विकल्प है? – Hunt

3

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

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

मैंने इस धागे में चर्चा के बाद इसे विकसित किया: Encoding binary data within XML : alternatives to base64

0

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

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

उदाहरण के लिए यदि आपके सर्वर HTTP के माध्यम से संवाद और आप एक बहुखण्डीय दस्तावेज़ भेजना चाहते हैं, प्राथमिक एक XML दस्तावेज है जो एक बाइनरी डेटा के लिए संदर्भित करता जा रहा है, 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-- 

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

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

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

लेकिन इस बेस 64 भूमि के ऊपर है।