문제

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

업데이트:나는 이것을 Base64 의 수업 아파치 커먼즈 코덱 라이브러리, 다른 사람이 비슷한 것을 시도하는 경우를 대비해.

도움이 되었습니까?

해결책

base64를 사용하여 이진 데이터를 인코딩하고 이를 Base64 요소에 넣을 수 있습니다.아래 기사는 이 주제에 관해 꽤 좋은 기사입니다.

XML 문서의 이진 데이터 처리

다른 팁

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은 폭력과 같습니다. 문제가 해결되지 않으면 XML을 충분히 사용하지 않는 것입니다.

편집하다:

지금:Base64 + CDATA가 아마도 최고의 솔루션일 것입니다.

(편집2:
나를 업모드하는 사람이 있으면 실제 답변도 업모드하세요.우리는 불쌍한 영혼이 여기에 와서 내 방법이 SO에서 가장 높은 순위였기 때문에 실제로 구현하는 것을 원하지 않습니다. 그렇죠?)

Base64는 실제로 정답이지만 CDATA는 그렇지 않습니다. 기본적으로 다음과 같습니다."이것은 무엇이든 될 수 있다", 그러나 그것은 반드시 ~ 아니다 무엇이든 Base64로 인코딩된 바이너리 데이터여야 합니다.XML 스키마 정의 기본 데이터 유형인 Base 64 바이너리 xsd에서 사용할 수 있습니다.

지난주에이 문제가 발생했습니다.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>

나는 보통 바이너리 데이터를 다음과 같이 인코딩합니다. MIME 베이스64 또는 URL 인코딩.

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

아마도 알려진 세트로 인코딩할 수도 있습니다. 기본 64와 같은 것이 널리 사용되는 선택입니다.

어느 바이너리를 텍스트로 인코딩 트릭을 할 것입니다.나는 그런 것을 사용한다

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

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

:인코딩 전략 base64/63으로 인해 uuencode et al.인코딩을 사용하면 저장하고 전송해야 하는 데이터 양(오버헤드)이 약 40% 증가합니다.yEnc는 1~2%).인코딩하는 내용에 따라 40%의 오버헤드가 문제가 될 수 있습니다.


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

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

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

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

당신은 또한 수 Uuencode 원래 이진 데이터입니다.이 형식은 약간 오래되었지만 base63 인코딩과 동일한 기능을 수행합니다.

XML 형식을 제어할 수 있다면 문제를 뒤집어야 합니다.이진 XML을 첨부하는 대신 여러 부분으로 구성된 문서(그 중 하나에는 XML이 포함되어 있음)를 묶는 방법을 생각해야 합니다.

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

예를 들어, 서버가 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 오버헤드가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top