扁平化XML,更改节点,然后添加到C#中的字典中

本文关键字:字典 添加 然后 XML 节点 扁平化 | 更新日期: 2023-09-27 18:27:06

这是我的超长XML(超过223个节点)的一部分

<ApplicationExtraction>
<ApplicationDate>10/06/2015</ApplicationDate>
<Status>Application Received</Status>
<EquipmentType>Equipment</EquipmentType>
<GetActiveLeaseApplicationParties>
<Item>
<RelationshipType>Primary Lessee</RelationshipType>
<PartyNumber>20000107</PartyNumber>   
<FirstName>Parvesh</FirstName>
<LastName>Musharuf</LastName>
<DateOfBirth>12/12/1993</DateOfBirth>
<CreationDate>10/06/2015</CreationDate>
</Item>
<Item>
<RelationshipType>Co-Lessee</RelationshipType>
<PartyNumber>20000108</PartyNumber>
<IsCorporate>No</IsCorporate>
<FirstName>Pary</FirstName>
<LastName>Mushroom</LastName>
<DateOfBirth>1/12/1953</DateOfBirth>
<CreationDate>10/06/2015</CreationDate>   
</Item>
</GetActiveLeaseApplicationParties>
</ApplicationExtraction>

我创建了字典Dictionary<string, string> xmlData = new Dictionary<string, string>();,并希望添加node作为关键字,添加nodevalue作为值。

我得到了它的一部分工作,直到第二项子节点。它给我的错误是"已经添加了具有相同密钥的项目"。现在我想将序列号添加到节点Item,这样我就不会出现这个错误。理想情况下,我想要这样的东西:

ApplicationExtraction.GetActiveLeaseApplicationParties.Item1.RelationshipType
ApplicationExtraction.GetActiveLeaseApplicationParties.Item1.PartyNumber
ApplicationExtraction.GetActiveLeaseApplicationParties.Item1.FirstName
ApplicationExtraction.GetActiveLeaseApplicationParties.Item2.RelationshipType   
ApplicationExtraction.GetActiveLeaseApplicationParties.Item2.PartyNumber

有可能做到这一点吗?我试图捕捉错误并拆分字符串以放入数字,但不知道如何增加序列,可能我得到了:

ApplicationExtraction.GetActiveLeaseApplicationParties.Item1.RelationshipType
ApplicationExtraction.GetActiveLeaseApplicationParties.Item2.PartyNumber
ApplicationExtraction.GetActiveLeaseApplicationParties.Item3.FirstName

这是我的密码。结果只包含路径(节点)和值

foreach (var p in result)   
    {   try
        {   key = p.Path;
            value =p.Value;
            xmlData.Add(key,value); }
        catch (Exception exc)
        {   i++;            
            if (exc.Message == "An item with the same key has already been added.")                             
            {
                pos = key.IndexOf("Item");
                if (pos !=-1 )
                {   
                    strTemp1 = key.Substring(0,key.IndexOf("Item")+4);
                    strTemp2 = key.Substring(pos + 4,key.Length - pos - 4);
                }   
                key = strTemp1 + "[" +  i.ToString() + "]" + strTemp2;
                value =p.Value;
                xmlData.Add(key,value);                     
            }
                        }

扁平化XML,更改节点,然后添加到C#中的字典中

您是否尝试在调试器中逐步完成?

假设循环顶部的i equals 0

对于第一次迭代,您将添加Item.RelationshipTypeItem.PartyNumber

对于第二项,您在Item.RelationshipType处获得异常,而将使用Item[1].RelationshipType

对于第二项本身,您也将获得Item.PartyNumber的异常,i将递增为2,您将使用的密钥将为Item[2].PartyNumber

这就是为什么你看到你看到的钥匙。

有多种方法可以获得正确的密钥。一种是跟踪当前项目编号,当您看到<item>标记时,可以增加该编号,并将其用于所有子元素。

您可以创建元组列表它可以收集xml的所有值。将xml中的每个项目添加到列表中

List.Add(Tuple.Create((Relationship.value,PartyNumber.value...);

要获取列表中的每一个,请给出lst[i].item1,lst[i].item2,它将为您提供xml Item[i].RelationshipValue,Item[i].PartyNumbervalue

下面是我的操作方法。如果你得到一个键已经存在的错误,那是因为你的字典有重复的键。我会用PartyNumber作为字典里的关键字。如果零件号有多个条目,则字典必须定义为dictionary>。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication61
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<ApplicationExtraction>" +
                    "<ApplicationDate>10/06/2015</ApplicationDate>" +
                    "<Status>Application Received</Status>" +
                    "<EquipmentType>Equipment</EquipmentType>" +
                    "<GetActiveLeaseApplicationParties>" +
                        "<Item>" +
                            "<RelationshipType>Primary Lessee</RelationshipType>" +
                            "<PartyNumber>20000107</PartyNumber>" +
                            "<FirstName>Parvesh</FirstName>" +
                            "<LastName>Musharuf</LastName>" +
                            "<DateOfBirth>12/12/1993</DateOfBirth>" +
                            "<CreationDate>10/06/2015</CreationDate>" +
                        "</Item>" +
                        "<Item>" +
                            "<RelationshipType>Co-Lessee</RelationshipType>" +
                            "<PartyNumber>20000108</PartyNumber>" +
                            "<IsCorporate>No</IsCorporate>" +
                            "<FirstName>Pary</FirstName>" +
                            "<LastName>Mushroom</LastName>" +
                            "<DateOfBirth>1/12/1953</DateOfBirth>" +
                            "<CreationDate>10/06/2015</CreationDate>" +
                        "</Item>" +
                    "</GetActiveLeaseApplicationParties>" +
                "</ApplicationExtraction>";
            XDocument doc = XDocument.Parse(xml);
            Dictionary<int, Item> dict = new Dictionary<int, Item>();
            foreach (XElement item in doc.Descendants("Item").AsEnumerable())
            {
                Item newItem = new Item() {
                    relationshipType = item.Element("RelationshipType").Value,
                    partyNumber = int.Parse(item.Element("PartyNumber").Value),
                    isCorporate = item.Element("IsCorporate") == null ? false :
                       item.Element("IsCorporate").Value  == "Yes" ? true : false,
                    firstName = item.Element("FirstName").Value,
                    lastName = item.Element("LastName").Value,
                    dateOfBirth = DateTime.Parse(item.Element("DateOfBirth").Value),
                    creationDate = DateTime.Parse(item.Element("CreationDate").Value)
                };
                dict.Add(newItem.partNumber, newItem);
            }
        }
        public class Item
        {
            public string relationshipType { get; set; }
            public int partyNumber { get; set; }
            public Boolean isCorporate { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public DateTime  dateOfBirth { get; set; }
            public DateTime creationDate { get; set; }
        }
    }

}