【问题标题】:Issue creating XML doc from Dictionary从字典创建 XML 文档的问题
【发布时间】:2014-10-01 15:12:43
【问题描述】:

我的意图是遍历我可爱的字典(键和值都是字符串)并从中创建一个 xml 文件。

我在最后一行得到错误(保存 xml)。

"InvalidOperationException 未处理 状态 Document 中的令牌 EndDocument 将导致无效的 XML 文档。”

使用断点查看此内容,似乎在到达此内容的末尾时,仅完成了初始位(在 for each 循环之外)..

我一半是在问我犯了什么愚蠢的错误,我一半是在问是否有更雄辩的方式来做到这一点。

如果我遗漏了什么,请告诉我,如果我有,我会补充。

XDocument xData = new XDocument(
                   new XDeclaration("1.0", "utf-8", "yes"));

foreach (KeyValuePair<string, string> kvp in inputDictionary)
{ 
        xData.Element(valuesName).Add(
            new XElement(valuesName, 
            new XAttribute("key", kvp.Key),
            new XAttribute("value", kvp.Value)));
}

xData.Save("C:\\xData.xml");

【问题讨论】:

  • 您能否提供有关您的代码的更多详细信息,例如什么是 xDoc 和 valuesName?
  • 确实 - 你有 xData 被你忽略,但不是 xDoc。目前您的xData 文档just 有一个XML 声明......它甚至没有根元素。请提供一个简短但完整的程序来说明问题。
  • 对,对不起,谢谢大家指出这一点。我现在已经编辑了。当我试图弄清楚我做错了什么时,我尝试了另一个 xDocument,但现在这一切都涉及 xData(只是一个错字)。编辑了以上内容。
  • @Jonny:这就是为什么提供一个简短但完整示例很有用的原因,其他人可以复制、粘贴、编译和运行该示例(除非您报告编译错误)。

标签: c# dictionary linq-to-xml


【解决方案1】:

目前您正在向文档中添加多个元素直接 - 因此您最终会得到 no 根元素(如果字典为空)或可能 多个 根元素(如果字典中有多个条目)。你想要一个根元素,然后是你的字典元素。此外,您尝试查找一个名为 valuesName 的元素,而无需添加任何内容,因此如果有任何字典条目,您实际上会得到一个 NullReferenceException

幸运的是,它比您做的更容易,因为您可以使用 LINQ 将您的字典转换为一系列元素并将其放入文档中。

var doc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement("root",
        inputDictionary.Select(kvp => new XElement(valuesName,
                                           new XAttribute("key", kvp.Key),
                                           new XAttribute("value", kvp.Value)))));
doc.Save(@"c:\data.xml");

完整的示例应用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

class Test
{    
    static void Main()
    {
        XName valuesName = "entry";
        var dictionary = new Dictionary<string, string>
        {
            { "A", "B" },
            { "Foo", "Bar" }
        };
        var doc = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"),
            new XElement("root",
                dictionary.Select(kvp => new XElement(valuesName,
                                               new XAttribute("key", kvp.Key),
                                               new XAttribute("value", kvp.Value)))));
        doc.Save("test.xml");
    }
}

输出(不保证输入顺序):

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
  <entry key="A" value="B" />
  <entry key="Foo" value="Bar" />
</root>

对此的另一种分类是:

var elements = inputDictionary.Select(kvp => new XElement(valuesName,
                                       new XAttribute("key", kvp.Key),
                                       new XAttribute("value", kvp.Value)));
var doc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement("root", elements));

您可能会发现这更容易阅读。

【讨论】:

  • 完美的伴侣,非常感谢。我基本上削减了我所做的并按照您的指示进行操作,效果很好。
【解决方案2】:

试试下面的

XDocument xData = new XDocument(
                   new XDeclaration("1.0", "utf-8", "yes"));

               XElement myXml = new XElement("paramList");// make sure your root and your descendents do not shre same name
               foreach (var entry in MyList)
                {
                       myXml.Add(new XElement(valuesName,
                                new XElement("key", entry.key),
                                new XElement("value", entry.Value)
               ));

xData.Add(myXml);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多