이진 데이터를 XML에 어떻게 포함합니까?


107

네트워크를 통해 XML 메시지를 사용하여 서로 통신하는 Java로 작성된 두 개의 응용 프로그램이 있습니다. 수신 측에서 SAX 파서를 사용하여 메시지에서 데이터를 다시 가져옵니다. 요구 사항 중 하나는 XML 메시지에 이진 데이터를 포함하는 것이지만 SAX는 이것을 좋아하지 않습니다. 누구든지 이것을하는 방법을 알고 있습니까?

업데이트 : 다른 사람이 비슷한 것을 시도하는 경우 아파치 커먼즈 코덱 라이브러리Base64 클래스 와 함께 작동 합니다.

답변:



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 :
누가 나를 upmods, 진짜 대답도 upmod하십시오. 우리는 가난한 영혼이 여기에 와서 실제로 내 방법을 구현하는 것을 원하지 않습니다.


9
진지한 사람이라면 XML을 완전히 부끄럽게 사용하는 것입니다. 그렇지 않다면, 높은 수준의 생각과 낮은 수준의 글을 쓰지 않는 초보자는 어떻게 알 수 있을까요?
TheFlash 2009

1
재미 있다고 생각합니다. 그러나 예, 다시 한 번 실제 base64 데이터 유형을 사용하는 것이 좋습니다. CData가 너무 일반적입니다.
Omniwombat

4
나는 그것이 충분히 설명 적이 지 않다고 생각한다. 아마도 축약 형 'BIT'보다는 'BINARYDIGIT'를 사용해야 할까? ;-)
리 앳킨슨

와. 이렇게하면 평균 킬로바이트 범위 파일이 약 230 배 더 커집니다. :)
Nyerguds 2011-08-08

36
오 젠장. 이것은 농담이었습니다. 나는 무엇을 했는가?! : thedailywtf.com/Articles/The-HumanReadable-Encryption-Key.aspx
Mo.

26

Base64가 실제로 정답이지만 CDATA는 그렇지 않습니다. 기본적으로 "이것은 무엇이든 될 수 있습니다"라고 말하지만, 그저 아무것도 아니 어야 하며 Base64로 인코딩 된 바이너리 데이터 여야합니다. XML 스키마는 Base 64 바이너리를 xsd에서 사용할 수 있는 기본 데이터 유형으로 정의합니다 .


2
xs:base64Binary사용하기에 적합한 유형 인 데이터 유형 을 언급하기위한 추가 요점 .
Christopher Schultz

14

지난주에이 문제가 발생했습니다. 나는 PDF 파일을 직렬화하여 XML 파일 안에 서버로 보내야했다.

.NET을 사용하는 경우 바이너리 파일을 base64 문자열로 직접 변환하여 XML 요소 안에 붙일 수 있습니다.

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();

문자열 abc는 다음과 같이 보입니다.

<?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 붙여 넣기
엘드 수수께끼


5

바이너리 데이터를 Base64 인코딩 / 디코딩 해보세요. CDATA 섹션도 살펴보십시오.


4

알려진 세트로 인코딩 할 수 있습니다. base 64와 같은 것이 인기있는 선택입니다.



4

Base64 오버 헤드는 33 %입니다.

XML1.0 용 BaseXML 오버 헤드는 20 %에 불과 합니다. 그러나 그것은 표준이 아니며 아직 C 구현 만 있습니다. 데이터 크기가 걱정된다면 확인하세요. 그러나 브라우저는 덜 필요하도록 압축을 구현하는 경향이 있습니다.

이 스레드에서 논의한 후에 개발했습니다 . XML 내의 이진 데이터 인코딩 : base64의 대안 .


4

다른 답변은 대부분 괜찮지 만 yEnc와 같은 더 공간 효율적인 인코딩 방법을 시도해 볼 수 있습니다. ( yEnc wikipedia link ) yEnc를 사용하면 "즉시"체크섬 기능을 사용할 수도 있습니다. 아래를 읽고 링크하십시오. 물론 XML에는 기본 yEnc 유형이 없기 때문에 인코딩 된 노드를 올바르게 설명하도록 XML 스키마를 업데이트해야합니다.

이유 : 인코딩 전략 base64 / 63으로 인해 uuencode et al. 인코딩은 저장 및 전송에 필요한 데이터 양 (오버 헤드)을 약 40 % 증가시킵니다 (vs. yEnc의 1-2 %). 인코딩하는 항목에 따라 40 %의 오버 헤드가 문제가 될 수 있습니다.


yEnc-Wikipedia 요약 : https://en.wikipedia.org/wiki/YEnc yEnc는 Usenet의 메시지 또는 이메일을 통해 바이너리 파일을 전송하기위한 바이너리-텍스트 인코딩 체계입니다. ... uuencode 및 Base64와 같은 이전 인코딩 방법에 비해 yEnc의 또 다른 이점은 디코딩 된 파일이 그대로 전달되었는지 확인하는 CRC 체크섬을 포함한다는 것입니다.


2
@Jamine 그래서 다른 대안이 있습니까?
Hunt

제이미, 이건 좀 더 많은 작업을한다면 괜찮은 대답이 될 수 있습니다. 나는 내 -1을 제거하고 노력을 기울이면 +1 할 것입니다. 후속 조치를 취하면 나를 신고하십시오.
Paul Sasik 19-01-13

Jamie, n / m. 귀하의 답변을 업데이트하고 원래 전달하려는 정보로 +1했습니다. 살짝 들여다보고 적절하다고 생각되는대로 업데이트하십시오. (저는 한동안 SO에서 활동하지 않았습니다. 답을 조사하고 편집하는 것이 즐거웠습니다. 그 과정에서 몇 가지 새로운 것을 배웠기 때문에 +1했습니다. 그게 전부입니다 ...? 건배.)
Paul Sasik

이스케이프리스 는 예측 가능 / 고정 오버 헤드가 중요한 경우 yEnc의 대안이 될 수 있습니다.
Ivan Kosarev


0

XML 형식을 제어 할 수 있다면 문제를 완전히 해결해야합니다. 바이너리 XML을 첨부하는 대신 여러 부분이 포함 된 문서를 묶는 방법에 대해 생각해야합니다. 그중 하나에는 XML이 포함되어 있습니다.

이에 대한 전통적인 해결책은 아카이브 (예 : tar)입니다. 그러나 포함하는 문서를 텍스트 기반 형식으로 유지하고 싶거나 파일 보관 라이브러리에 액세스 할 수없는 경우에는 multipart / * MIME 와 함께 이메일 및 HTTP에서 많이 사용되는 표준화 된 체계도 있습니다. 콘텐츠 전송 인코딩 : 바이너리 .

예를 들어 서버가 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--

위의 예에서와 같이 XML cid은 Content-Id 헤더에 대한 식별자 인 URI 스킴을 사용하여 엔 클로징 멀티 파트의 이진 데이터를 참조합니다 . 이 체계의 오버 헤드는 MIME 헤더뿐입니다. HTTP 응답에도 유사한 체계를 사용할 수 있습니다. 물론 HTTP 프로토콜에서는 멀티 파트 문서를 별도의 요청 / 응답으로 보내는 옵션도 있습니다.

다중 부분에서 데이터를 래핑하지 않으려면 데이터 URI를 사용하는 것입니다.

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

그러나 이것은 base64 오버 헤드가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.