如何将二进制数据附加到XML文件中特定位置的特定节点

时间:2011-03-30 18:02:55

标签: c# .net xml linq-to-xml

我们正在使用XML文件来保存我们的数据,这是双倍的。由于我们的数据非常庞大,因此在GB范围内,我们将其转换为字节,以节省磁盘空间和访问时间。此外,我们将数据写入少量MB的数据块中,新数据块也可以来自与前一个数据源相同的源或来自不同的源。对于每个新源,我们在XML文件中创建了一个元素,以便将来轻松识别来自该源的数据。 我们面临的问题是,如何识别与XML文件中的源相对应的元素,然后将与该源相对应的数据附加到已在XML文件中捕获的数据中。我正在使用Linq到XML,并且无法使用此方法谷歌任何解决方案。我尝试了XMLWriter类,但使用它的问题是如何识别或到达我想要编写块的元素。

2 个答案:

答案 0 :(得分:1)

XML不是编写大量二进制数据的好格式(由于需要将二进制数据存储为Base64字符串或其他一些字符串安全编码),也不适合在大文档中间更新数据块。我建议重新考虑你的文件格式。

如果你必须使用XML:

  • 确保您的字节数组在写入XML时是Base64编码
  • 如果要在中间插入数据,则必须复制XML。考虑使用XmlReader和XmlWriter。将源XML复制到您想要添加数据的位置,将数据添加到输出编写器,然后完成复制XML的剩余部分。
  • 避免将整个XML加载到内存中,因为lilky会导致您的GB数据范围出现问题。

答案 1 :(得分:0)

我确定我没有完整的图片,但很难理解为什么你不使用数据库。然而,为了跟进Alexei的帖子,这是一个人为的例子,说明如何使用XmlReader和XmlWriter来完成我认为你想做的事情:

//start with some dummy data
string bigData = "<bigdata><rec id='1'>1234</rec><rec id='2'>2468</rec></bigdata>";
string criterion = "2";
string append = "10";
string newValue = "";
bool match = false;
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb))
{
    using (XmlReader reader = XmlReader.Create(new StringReader(bigData)))
    {
    while (reader.Read())
    {
    switch (reader.NodeType)
    {
    case XmlNodeType.Element:
        if (reader.LocalName == "rec")
        {
            match = reader.GetAttribute("id").ToString() == criterion;
        }
        writer.WriteStartElement(reader.LocalName);
        writer.WriteAttributes(reader, true);
        if (reader.IsEmptyElement)
        {
            writer.WriteEndElement();
        }
        break;
    case XmlNodeType.Text: // do the append here
        newValue = match ? reader.Value + append : reader.Value;
        writer.WriteString(newValue);
        break;
    //other cases based on node types
    case XmlNodeType.EndElement:
        writer.WriteFullEndElement();
        break;
    }                                                                      
    }
        writer.Flush();
        string x = sb.ToString();//output
    }                         
}