【问题标题】:How to read the xml file and write to the dictionary如何读取xml文件并写入字典
【发布时间】:2018-11-21 08:51:57
【问题描述】:

我真的需要帮助。我有一个具有以下结构的 xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<Head xmlns="http://www.sample-package.org">
    <Number>748</Number>
    <Number_confirm>977</Number_confirm>
    <Positions>
        <Tare_id>2442</Tare_id>
    </Positions>
    <Positions>
        <Product_id>168813</Product_id>
    </Positions>
</Head>

我需要在字典中添加键和值(N 和“数字”)、(id 和 Product_id),但需要在没有 linq 的情况下执行此操作,例如:

//load xml from url
doc.Load(temp);

var root = doc.GetElementsByTagName("Head");
var documents = new List<Dictionary<string, object>>();
for (int i = 0; i <root.Count; i++)
{
    for (int j = 0; j < root[i].ChildNodes.Count; j++)
    {

        var element = root[i].ChildNodes[j];
        InfoManager.MessageBox("element:{0}", element.Value);
        var document = new Dictionary<string, object>();
        document.Add("N", element.Attributes.GetNamedItem("Number"));
        document.Add("NC", element.Attributes.GetNamedItem("Number_confirm"));
        documents.Add("ID",
        element.Attributes.GetNamedItem("Product_id"));
        documents.Add(document);

    }

}

现在 element.Attributes = null,MessageBox 显示元素为空,我看不到 Attributes/Element 并且没有将所有元素添加到字典中。我该如何解决??

【问题讨论】:

  • 您要查找的值不是属性。 xml 属性类似于&lt;tag attribute="value"&gt;&lt;/tag&gt;。我建议您阅读 XML 和相应的 .net 类。您可能会发现使用 XPath 表达式来获取您正在寻找的信息更容易,因此您可能也想探索一下。

标签: c# xml parsing


【解决方案1】:

1) element 没有任何价值。要获得您要查找的号码,您必须使用element.InnerText,如下所示:

MessageBox.Show(string.Format("element:{0}", element.InnerText));

2) 然后在document.Add-Statements 中,您尝试访问属性,但您的元素上没有属性。

一个属性的例子是:

<Number MyAttribute="additionalInfo">67</Number>

3) 您的document.Add-Statements 中有一个拼写错误。您不小心输入了一次文档s

4) 在第二个循环中,循环遍历根(Head)中的所有元素。因此,您进入循环 4 次,每次获得不同的元素,但您尝试在每次迭代中添加所有值。您实际上希望有一个 KeyValuePairs 列表,如下所示:

var root = doc.GetElementsByTagName("Head");
var documents = new List<KeyValuePair<string, object>>();
for (int i = 0; i < root.Count; i++)
{
  for (int j = 0; j < root[i].ChildNodes.Count; j++)
  {
    var element = root[i].ChildNodes[j];
    MessageBox.Show(string.Format("element:{0}", element.InnerText));
    var document = new KeyValuePair<string, object>(element.Name, element.InnerText);
    documents.Add(document);
  }
}

现在字典等于您的 xml 的结构:一个对象(头)有一个 KeyValuePair 列表(“数字”对与“748”,“Number_confirm”对与“977”等)


正如您的评论所暗示的,如果您的 xml 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Head xmlns="http://www.sample-package.org">
    <Number>748</Number>
    <Number_confirm>977</Number_confirm>
    <Positions> <!-- Note: two numbers in one Positions-element -->
        <Tare_id>2442</Tare_id>
        <Product_id>168813</Product_id>
    </Positions>
</Head>

..那么您将不得不添加另一个循环以更深入并更改以下内容:

..
var element = root[i].ChildNodes[j];
MessageBox.Show(string.Format("element:{0}", element.InnerText));

string numbers = string.Empty;
for(int z = 0; z < element.ChildNodes.Count; z++)
{
  numbers += element.ChildNodes[z].InnerText + Environment.NewLine;
}

var document = new KeyValuePair<string, object>(element.Name, numbers);
documents.Add(document);
..

尽管如此,我还是建议您使用 xml 中的属性创建一个类,这样您就可以在内部加载 xml 并随意打印/更改它。

【讨论】:

  • 首先您将文档创建为一个空的 KeyValuePair,然后立即创建一个新的 KeyValuePair,其中包含键和值的值,因此您可以省略第一个构造函数调用。
  • @StefanIllner,你是对的,谢谢。我最初让它是一个更一步一步的代码,但我现在合并了这些语句。
  • 如果元素 有几个项目,如 &lt;Positions&gt; &lt;Tare_id&gt;2442&lt;/Tare_id&gt; &lt;Product_id&gt;168813&lt;/Product_id&gt; 然后我在控制台文本 (2442168813) 中看到 1 行中的所有元素。如何使用每行中的每个键和值(2442 和值 168813 的新行)编写代码
  • 要在字符串中添加新行,您应该使用Environment.NewLine。在你的情况下,你可能应该在你的数字之间打印一个新行,没有我不知道的代码,新问题在哪里。但是,如果答案解决了原始问题中的问题,我恳请您通过勾选复选标记来接受答案或编辑您的问题以解决更多问题。
【解决方案2】:

尝试使用 XmlDocument 并将其转换为 JSON 对象。

XmlDocument doc = new XmlDocument();
doc.Load(*XML FILE PATH*);
string XML_JSON = JsonConvert.SerializeXmlNode(doc);

dynamic jsonObject = JsonConvert.DeserializeObject(XML_JSON);
var XML_OBJECT = jsonObject["Head"];

JToken number = (JToken) XML_OBJECT["Number"]
JToken numberConfirm = (JToken) XML_OBJECT["Number_confirm"];
JArray positions = (JArray) XML_OBJECT["Positions"];

然后按照您希望添加到字典中的方式对其进行迭代。

仅供参考,您的 XML 文件中没有任何属性。

【讨论】:

    【解决方案3】:

    您提供的 Xml 文档以

    作为根元素,因此 foreach 循环将始终只遍历一个元素以及字典列表。

    但这可能只是一个简短的例子。为了得到你想要的,你可以像这样使用 XPath 找到你想要的元素:

    doc.Load(temp);
    
    XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
    nsMgr.AddNamespace("pkg", "http://www.sample-package.org");
    var root = doc.GetElementsByTagName("Head");
    var documents = new List<Dictionary<string, object>>();
    for (int i = 0; i < root.Count; i++)
    {
        var head = root[i];
        var document = new Dictionary<string, object>();
        document.Add("N", head.SelectSingleNode("/pkg:Head/pkg:Number", nsMgr).InnerText);
        document.Add("NC", head.SelectSingleNode("/pkg:Head/pkg:Number_confirm", nsMgr).InnerText);
        document.Add("ID", head.SelectSingleNode("/pkg:Head/pkg:Positions/pkg:Product_id", nsMgr).InnerText);
        documents.Add(document);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 2018-03-19
      相关资源
      最近更新 更多