Olá Ivaldo, trabalhar com arquivos anexo em um xml, nada mais é do que trabalhar com um xml onde em determinada tag vai estar em o arquivo.
Eu tenho experiencia com base64, mas acredito que seja o mesmo principrio. Entao vamos analisar o seguinte exemplo:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<Q-ENV:Header>
</Q-ENV:Header>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<Q-ENV:Body>
<Q-ENV:Content-Type>text/xml</Q-ENV:Content-Type>
<Q-ENV:Message-Type>xCBL</Q-ENV:Message-Type>
<Q-ENV:Encoding>UTF-8</Q-ENV:Encoding>
<Q-ENV:Message-Body>
</Q-ENV:Message-Body>
</Q-ENV:Body>
<Q-ENV:Anexo>
Arquivo em Anexo, do tipo Binário ou Base 64
</Q-ENV:Anexo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Então como podemos ver dentro da Tag <Q-Env:Anexo> vai estar o arquivo em anexo.
Segue aqui um código C# de como pegar um arquivo de um diretório, compactar o arquivo e transformá-lo em base64
FileStream arqTXT = new FileStream(@"E:\VS Projetos\VC\VC.EDICartaFrete\OUT\4026_999_CAR01.txt", FileMode.Open);
StreamReader readerTXT = new StreamReader(arqTXT);
string sTXT = readerTXT.ReadToEnd();
MemoryStream memStrm = new MemoryStream();
StreamWriter swriter = new StreamWriter(memStrm, System.Text.Encoding.Default);
swriter.Write(sTXT);
swriter.Flush();
memStrm.Seek(0, System.IO.SeekOrigin.Begin);
string arqZipadoBase64 = CompactarArquivo(memStrm, "4026_999_CAR01.txt");
byte[] filebytes = Convert.FromBase64String(arqZipadoBase64);
FileStream arq = new FileStream(@"E:\VS Projetos\VC\VC.EDICartaFrete\OUT\ARQUIVO_4026_999_CAR01_compactado.zip", FileMode.Create, FileAccess.Write, FileShare.None);
arq.Write(filebytes, 0, filebytes.Length);
arq.Close();
Então o arquivo estaria na string arqZipadoBase64, agora o trabalho seria somente colocar essa string dentro de uma tag do xml.
Coloco aqui um exemplo de código em xslt onde executo a mesma função CompactarArquivo, em uma dll externa.
<xsl:variable name ="vNomeArq">
<xsl:for-each select ="s0:ZHATT01000000GRP">
<xsl:value-of select ="concat(s0:ZHATT01000/s0:LINE/text(), ',')"/>
</xsl:for-each>
</xsl:variable>
<xsl:element name ="Q-ENV:Message-Body">
<xsl:value-of select ="ScriptNS0:CompactarArquivo($vAnexo, $vNomeArq)"/>
</xsl:element>
</xsl:element>
Segue aqui a função CompactarArquivo, pois é nela que eu tranformo o arquivo na memória para string base64.
static string CompactarArquivo(Stream strmFile, string sNomeArq)
{
MemoryStream ms = new MemoryStream();
ZipOutputStream arqZip = new ZipOutputStream(ms);
arqZip.SetLevel(9);
ZipEntry entry = new ZipEntry(sNomeArq);
entry.DateTime = DateTime.Now;
arqZip.PutNextEntry(entry);
byte[] oBuffer = new byte[strmFile.Length];
strmFile.Read(oBuffer, 0, oBuffer.Length);
arqZip.Write(oBuffer, 0, oBuffer.Length);
arqZip.Finish();
arqZip.Close();
byte[] bArqComp = ms.ToArray();
return Convert.ToBase64String(bArqComp);
}
Espero ter ajudado
Ruth Resende
MVP, MCTS - Biztalk Server
www.biztalkbrasil.com.br
Twitter:
@ruthresende