【问题标题】:parse XML file using nested dictionary [duplicate]使用嵌套字典解析 XML 文件 [重复]
【发布时间】:2017-06-28 08:00:20
【问题描述】:

我有以下 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 获得所需的层次结构? 我想要完成的主要事情是: 为每条消息获取它的字段。

例如,对于 5 号消息,我想保存 所有字段(保留层次结构)。这意味着 nameentry(字节偏移量和字节大小)。

【问题讨论】:

  • 为什么不直接使用 LINQ to XML?它允许你以任何你想要的方式查询 XML。嵌套字典听起来像一场噩梦。
  • 我更新了帖子。请看一下(:
  • 对于像&lt;Field/&gt; 这样的重复元素,您希望发生什么并不清楚。第一个标记的副本确实包含涉及该问题的答案。其他副本提供了替代方法。

标签: c# xml parsing dictionary


【解决方案1】:

您最好使用 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 以获取演示。

【讨论】:

  • 感谢您的回答,但我不想使用课程。我希望用户在不修改类的情况下修改 XML(添加/删除属性)。
  • @OrRosenblum 我不明白这有什么不同。如果用户添加了新元素或属性,如果它是类或某些字典结构,则需要在代码中处理它们。
  • @OrRosenblum 在不了解结构的情况下,我不确定这是否真的可行。 ByteOffset 包含一个嵌套的 offset 元素,其中包含您想要的值。如果一个字段有多个元素怎么办?不同的嵌套?属性?
  • 我想要的只是解析 XML 如下:对于每个 msgNumber 获取他的所有字段。例如,对于 msgNumber 5(XML 可以获得超过 1 个 msgNumber)获取名称和条目(ByteOffset 和 ByteSize)。我希望解析器将数据保存在字典中,以便我可以在我的代码中使用它......但我不想在我的代码中使用一个类,因为如果我向我的 XML 添加一个元素,我需要将它添加到类也是如此。
  • @OrRosenblum 如果向 XML 添加元素,则需要将其添加到代码某处。我看不出它在哪里有很大的不同。如果您真的不想使用类,我建议您直接使用 LINQ to XML - 将其视为元素/属性和值的分层字典 - 实际上就是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
  • 1970-01-01
  • 2018-04-02
  • 2015-01-11
  • 2021-06-22
  • 2018-09-05
  • 2021-10-25
相关资源
最近更新 更多