c# - 将 XDocument 转换为字节数组(并将字节数组转换为 XDocument)

标签 c# xml linq-to-xml bytearray

我接管了一个以二进制格式在 SQL Server 中存储大型 XML 文档的系统。

目前,数据是通过将其转换为字符串,然后将该字符串转换为字节数组来保存的。但最近在尝试转换为字符串时遇到一些大型 XML 文档出现内存异常,因此我想绕过此过程并直接从 XDocument 转换为字节数组。

保存 XML 的 Entity Framework 类已经扩展,因此二进制数据可以像这样作为字符串访问:

partial class XmlData
{
    public string XmlString { get { return Encoding.UTF8.GetString(XmlBinary); } set { XmlBinary = Encoding.UTF8.GetBytes(value); } }
}

我想进一步扩展这个类看起来像这样:

partial class XmlData
{
    public string XmlString{ get { return Encoding.UTF8.GetString(XmlBinary); } set { XmlBinary = Encoding.UTF8.GetBytes(value); } }

    public XDocument XDoc
    {
        get
        {
            // Convert XmlBinary to XDocument
        }
        set
        {
            // Convert XDocument to XmlBinary
        }
    }
}

我想我几乎已经弄清楚了转换,但是当我使用部分类 XmlString 方法从数据库中获取 XML 时,XML 总是在接近尾声时被切断,总是以不同的字符计数:

var memoryStream = new MemoryStream();
var xmlWriter = XmlWriter.Create(memoryStream);
myXDocument.WriteTo(xmlWriter);
XmlData.XmlBinary = memoryStream.ToArray();

解决方案

这是基本的转换:

var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Encoding = Encoding.UTF8 };
using (var memoryStream = new MemoryStream())
using (var xmlWriter = XmlWriter.Create(memoryStream, settings))
{
    myXDocument.WriteTo(xmlWriter);
    xmlWriter.Flush();
    XmlData.XmlBinary = memoryStream.ToArray();
}

但出于某种原因,在此过程中,一些奇怪的非 ascii 字符被添加到 XML 中,因此使用我以前的 XmlString 方法会加载这些奇怪的字符,并且 XDocument.Parse() 会中断,所以我的新部分类如下所示:

partial class XmlData
{
    public string XmlString 
    { 
        get 
        {
            var xml = Encoding.UTF8.GetString(XmlBinary);
            xml = Regex.Replace(xml, @"[^\u0000-\u007F]", string.Empty); // Removes non ascii characters
            return xml;
        } 
        set 
        { 
            value = Regex.Replace(value, @"[^\u0000-\u007F]", string.Empty); // Removes non ascii characters
            XmlBinary = Encoding.UTF8.GetBytes(value); 
        } 
    }

    public XDocument XDoc
    {
        get
        {
            using (var memoryStream = new MemoryStream(XmlBinary))
            using (var xmlReader = XmlReader.Create(memoryStream))
            {
                var xml = XDocument.Load(xmlReader);
                return xml;
            }
        }
        set
        {
            var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Encoding = Encoding.UTF8 };
            using (var memoryStream = new MemoryStream())
            using (var xmlWriter = XmlWriter.Create(memoryStream, settings))
            {
                value.WriteTo(xmlWriter);
                xmlWriter.Flush();
                XmlBinary = memoryStream.ToArray();
            }
        }
    }
}

最佳答案

这听起来像是在读取或写入期间未刷新流/写入器之一的缓冲区 - 使用 using (...) 进行自动关闭、刷新和处置,并在所有地方进行检查你完成了读/写 你已经完成了 .Flush()

关于c# - 将 XDocument 转换为字节数组(并将字节数组转换为 XDocument),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24282260/

相关文章:

c# - 是否有适用于 Windows 通用应用程序的 SharpDx 模板?

c# - 使用单个 TextBlock 来显示错误消息?

xml - 在 scala 中以 UTF-8 读取 xml

python - 使用 Python Requests 库上传大型 XML 文件

xml - 银光 3 : Converting XML stroke collection back into a strokecollection?

c# - 如果结构包含 DateTime 字段,为什么 LayoutKind.Sequential 的工作方式不同?

c# - 线程安全的缓存枚举器-使用yield锁定

c# - Linq to XML - 根据 if 语句设置 Xelement 值

c# - 使用 var 匿名对象为 LINQ 获取 InvalidCastException

c# - 如何比较 2 个 XML 文档?