代码之家  ›  专栏  ›  技术社区  ›  Nastya

如何读取XML文件并写入字典

  •  0
  • Nastya  · 技术社区  · 6 年前

    我真的需要帮助。我有一个具有以下结构的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和“number”),(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显示element为空,我看不到attributes/element,也没有将所有元素添加到字典中。我怎么修??

    3 回复  |  直到 6 年前
        1
  •  1
  •   RUL JohnnyQ    6 年前

    1) 这个 element 没有任何值。要得到你要找的号码,你必须使用 element.InnerText 如:

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

    2) 然后在 document.Add -语句,您试图访问属性,但元素上没有属性。

    属性的一个例子是:

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

    3) 你的一个打字错误 添加文件 -声明。您不小心输入了文档 S 曾经。

    (四) 在第二个循环中,循环遍历根(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的结构:一个对象(head)有一个keyValuePairs列表(“number”对与“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并随意打印/更改它。

        2
  •  1
  •   klitz    6 年前

    尝试使用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
  •  1
  •   Stefan Illner    6 年前

    您提供的XML文档具有<head>作为根元素,因此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);
    }