使用嵌套字典解析XML文件

时间:2017-06-28 08:00:20

标签: c# xml parsing dictionary

我有以下XML文件:

<myXML>
    <MyGroup>
        <source>OCU</source> 
        <endianity>
            <set>LITTLE</set><!--LITTLE/BIG Endian-->
        </endianity>
       <msgNumber>
          <Number>5</Number>
          <Field>
            <name>Pos_X</name>
            <entry>
                 <ByteOffset>
                    <offset>8</offset>
                 </ByteOffset>
                 <ByteSize>
                    <Size>4</Size>
                 </ByteSize>
            </entry>
          </Field>
          <Field>
            <name>Pos_Y</name>
            <entry>
                 <ByteOffset>
                    <offset>12</offset>
                 </ByteOffset>
                 <ByteSize>
                    <Size>4</Size>
                 </ByteSize>
            </entry>
          </Field>
       </msgNumber>
    </MyGroup>
</myXML>

我使用 XmlSerializer 将其解析为一个对象并且它有效。 我必须创建一个匹配该对象的类的唯一问题。 我的意思是这样的:

   xmlInputData = File.ReadAllText(newPath + xmlFileName);

    myXML messages = Deserialize<myXML>(xmlInputData);

我现在想要不用创建一个类 - 这意味着将XML直接解析为字典 - 如下所示:

Dictionary<MessageNumber, SecondDictionary>
                              |
                              |
                  SecondDictionary<FieldName, FieldValue>

如何使用 嵌套 词典解析它?如何保持与XML相同的层次结构?

修改

我尝试在LINQ中编写它,但它对我来说太复杂了:

  var doc = XDocument.Load(newPath + xmlFileName);
    var rootNodes = doc.Root.Descendants("msgNumber");
    var keyValuePairs = from n in rootNodes
                        select new
                        {
                            TagName = n.Name,
                            TagValue = n.Value
                        };


    Dictionary<string, string> allItems = new Dictionary<string, string>();
    foreach (var token in keyValuePairs)
    {
        allItems.Add(token.TagName.ToString(), token.TagValue.ToString());
    }

如何使用 LINQ 获得所需的层次结构? 我想要完成的主要事情是: 为每个消息获取它的字段。

例如,对于msg编号5,我想保存所有字段(保持层次结构)。这意味着名称条目(字节偏移和字节大小)。

1 个答案:

答案 0 :(得分:0)

使用LINQ to XML来获取实际需要的数据而不是尝试创建一些嵌套的字典结构会更好。据推测,无论如何,这实际上是你用嵌套词典的。

根据您获取名称和偏移量的要求,您可以创建两个类:

public class Message
{
    public int Number { get; set; }
    public List<Field> Fields { get; set; }
}

public class Field
{
    public string Name { get; set; }
    public int ByteOffset { get; set; }
    public int ByteSize { get; set; }
}

并编写如下查询:

var msgs =
    from msg in doc.Descendants("msgNumber")
    select new Message
    {
        Number = (int) msg.Element("Number"),
        Fields = msg
            .Elements("Field")
            .Select(x => new Field
            {
                Name = (string)x.Element("name"),
                ByteOffset = (int)x.Descendants("offset").Single(),
                ByteSize = (int)x.Descendants("Size").Single(),
            })
            .ToList()
    };

请参阅this fiddle了解演示。