c# - 从 xml 文档解码 base64 编码的数据

标签 c# xml base64 decode

我收到一些嵌入了 base64 编码图像的 xml 文件,我需要对其进行解码并另存为文件。

可以在下面下载此类文件的未修改(压缩除外)示例:

20091123-125320.zip (60KB)

但是,我收到诸如“Base-64 字符数组的长度无效”和“Base-64 字符串中的字符无效”之类的错误。我在代码中标记了我在代码中出现错误的行。

文件可能如下所示:

<?xml version="1.0" encoding="windows-1252"?>
<mediafiles>
    <media media-type="image">
      <media-reference mime-type="image/jpeg"/>
      <media-object encoding="base64"><![CDATA[/9j/4AAQ[...snip...]P4Vm9zOR//Z=]]></media-object>
      <media.caption>What up</media.caption>
    </media>
</mediafiles>

处理代码如下:

var xd = new XmlDocument();
xd.Load(filename);
var nodes = xd.GetElementsByTagName("media");

foreach (XmlNode node in nodes)
        {
            var mediaObjectNode = node.SelectSingleNode("media-object");
            //The line below is where the errors occur
            byte[] imageBytes = Convert.FromBase64String(mediaObjectNode.InnerText);
            //Do stuff with the bytearray to save the image
        }

xml 数据来自企业报纸系统,所以我很确定文件没问题 - 我处理它们的方式一定有问题,那是错误的。编码可能有问题?

我已经尝试写出 mediaObjectNode.InnerText 的内容,它是 base64 编码数据 - 因此导航 xml-doc 不是问题。

我一直在谷歌搜索、大口大口、stackoverflowing 和哭泣 - 没有找到解决方案...帮助!

编辑:

添加了一个实际的示例文件(和赏金)。请注意,可下载文件的架构略有不同,因为我在上面的示例中对其进行了简化,删除了不相关的内容...

最佳答案

第一次拍摄时我没有使用任何编程语言,只使用了 Notepad++

我打开其中的 xml 文件,将原始 base64 内容复制并粘贴到一个新文件中(没有方括号)。

之后我选择了所有内容 (Strg-A) 并使用选项扩展 - Mime 工具 - Base64 解码。这引发了关于错误文本长度的错误(必须是 mod 4)。所以我只是在末尾添加了两个等号 ('=') 作为占位符以获得正确的长度。

再次重试,它成功解码为“某物”。只需将文件另存为 .jpg 格式,它就可以在任何图片查看器中轻松打开。

所以我想说,您将获得的数据有问题。他们只是在末尾没有正确数量的等号来填充可以分成 4 个包的符号数。

“简单”的方法是添加等号,直到解码不会引发错误。更好的方法是计算字符数(减去 CR/LF!)并一步添加所需的字符。

进一步调查

经过一些编码和阅读 the convert function ,问题是生产者错误地附加了等号。 Notepad++ 处理大量等号没有问题,但 MS 的 Convert 函数仅适用于零、一个或两个等号。所以如果你用额外的等号填充已经存在的,你也会得到一个错误!要让这该死的东西发挥作用,您必须切断所有现有标志,计算需要多少,然后重新添加。

只是为了赏金,这是我的代码(不是绝对完美,但足以作为一个好的起点):;-)

    static void Main(string[] args)
    {
        var elements = XElement
            .Load("test.xml")
            .XPathSelectElements("//media/media-object[@encoding='base64']");
        foreach (XElement element in elements)
        {
            var image = AnotherDecode64(element.Value);
        }
    }

    static byte[] AnotherDecode64(string base64Decoded)
    {
        string temp = base64Decoded.TrimEnd('=');
        int asciiChars = temp.Length - temp.Count(c => Char.IsWhiteSpace(c));
        switch (asciiChars % 4)
        {
            case 1:
                //This would always produce an exception!!
                //Regardless what (or what not) you attach to your string!
                //Better would be some kind of throw new Exception()
                return new byte[0];
            case 0:
                asciiChars = 0;
                break;
            case 2:
                asciiChars = 2;
                break;
            case 3:
                asciiChars = 1;
                break;
        }
        temp += new String('=', asciiChars);

        return Convert.FromBase64String(temp);
    }

关于c# - 从 xml 文档解码 base64 编码的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1771242/

相关文章:

c# - 无法从 Lync 2013 sdk 获取可用的音频设备

c# - 保存的文件有时只包含 NUL 字符

c# linkedlist 如何获取最后一个元素之前的元素

css - 如何将 svg-glyph 转换为路径?

xml - XPath 子串

c# - Math.Pow 给出 "Cannot implicitly convert type ' double' to 'float' "error

xml - 如何在没有转义字符的情况下使用grails生成真正的UTF-8 XML?

javascript - base64的前缀 'data:image/png;base64,'对显示图像有影响吗?

java - Base64 不对整个字符串进行编码

javascript - 无法将 base64 png 图像添加到 JSPDF Javascript