展平XML,更改节点,然后在C#中添加到字典

时间:2015-12-15 22:56:41

标签: c# xml dictionary

这是我很长的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>();,并希望将节点添加为键,将节点值添加为值。

我的部分工作直到第二个Item子节点。它给了我错误#34;已经添加了具有相同键的项目&#34;。现在我想将序列号添加到节点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);                     
            }
                        }

3 个答案:

答案 0 :(得分:1)

您是否尝试在调试器中单步执行?

假设循环顶部有i equals 0

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

对于第二项,您会在Item.RelationshipType获得例外,而您将使用Item[1].RelationshipType

对于第二个项目本身,您将获得Item.PartyNumber的例外,i将增加到2,您将使用的密钥为Item[2].PartyNumber

这就是你看到你看到的钥匙的原因。

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

以下是我的表现方式。如果您收到密钥已存在的错误,则由于您的字典具有重复密钥。我会使用PartyNumber作为字典中的键。如果您的零件编号有多个条目,则必须将字典定义为字典&gt;。

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; }

        }
    }



}