【问题标题】:Parsing an XML file and creating a list of its contents解析 XML 文件并创建其内容列表
【发布时间】:2016-01-21 15:19:22
【问题描述】:

我正在尝试读取一个 XML 文件并解析其内容,但我无法从文件中提取参数。

我尝试解析的 XML 文件如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <register_map>
        <Register ID="1" Index="0x100000" DataType="0x0007" ObjectType="0x07" Name="Device Type"/>
        <Register ID="2" Index="0x100100" DataType="0x0005" ObjectType="0x07" Name="Error Register"/>
    </register_map>
</root>

到目前为止,我的代码如下所示

namespace Test_XML
{
    class Program
    {
        struct RegisterEntry
        {
            public UInt32 index;
            public UInt16 dataType;
            public UInt16 objectType;
            public string name;
        };

        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load("registers.xml");

            var registers = doc.Descendants("register_map");

            foreach (var register in registers)
            {
                // Fill up a list of RegisterEntrys with contents of XML
            }
            Console.ReadLine();
        }
    }
}

如何从“寄存器”中提取参数并将它们放入RegisterEntry 对象中?

【问题讨论】:

  • 你的DataType和ObjectType,是base8吗?

标签: c# .net xml linq-to-xml


【解决方案1】:

你可以使用

var registers = doc.XPathSelectElements("/root/register_map/Register");

它将为您提供Registernodes 的集合,因此您将能够访问它们的属性并填充您的RegisterEntry 对象,如下所示:

foreach (var register in registers)
{
    var dataType = register.Attribute("DataType").Value;
    //the rest of the code
}

注意XPathSelectElementsSystem.Xml.XPath 命名空间中的扩展方法。确保您已引用 System.Xml.Linq 程序集以便使用它。

【讨论】:

  • 像魅力一样工作。谢谢!
【解决方案2】:

您应该使用.Attributes["name"].Value。我认为您也希望将这些值转换为 Int,因此我们需要额外的 Convert.ToInt(string, base);

var RegisteryEntryList = new List<RegistryEntry>();

foreach (var register in registers)
{
    //create a new RegistryEntry
    var obj = new RegistryEntry();
    //convert your string to an int value and save it
    obj.index = Convert.ToInt32(register.Attributes["Index"].Value.Split('x')[1], 8);
    obj.datatype = Convert.ToInt32(register.Attributes["DataType"].Value.Split('x')[1], 8);

    //... your remaining properties
    RegisteryEntryList.Add(obj);
}

请注意:如果您的索引是二进制(以 2 为底),您需要相应地调整转换。欲了解更多信息,请参阅https://msdn.microsoft.com/en-us/library/1k20k614(v=vs.110).aspx

【讨论】:

    【解决方案3】:

    您的查询将为您提供名称为 register_map 的所有元素 - 您想要所有 Register 元素。改成这样:

    var registers = doc.Descendants("Registers");
    

    然后遍历它们并获取您需要的值,将它们转换为所需的类型。

    foreach (var register in registers)
    {
        var indexHex = (string)register.Attribute("Index");
        var index = Convert.ToUInt32(indexHex, 16);
    
        var dataTypeHex = (string)register.Attribute("DataType");
        var dataType = Convert.ToUInt16(dataTypeHex, 16);
    
        var objectTypeHex = (string)register.Attribute("ObjectType");
        var objectType = Convert.ToUInt16(objectTypeHex, 16);
    
        var name = (string)register.Attribute("Name");
    
        var entry = new RegisterEntry
        {
            index = index,
            dataType = dataType,
            objectType = objectType,
            name = name,
        };
    
        // do something with entry
    }
    

    【讨论】:

      【解决方案4】:

      使用 xml Linq

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Linq;
      using System.Globalization;
      
      namespace ConsoleApplication1
      {
          class Program
          {
              static void Main(string[] args)
              {
                  string xml =
                      "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                      "<root>" +
                          "<register_map>" +
                              "<Register ID=\"1\" Index=\"0x100000\" DataType=\"0x0007\" ObjectType=\"0x07\" Name=\"Device Type\"/>" +
                              "<Register ID=\"2\" Index=\"0x100100\" DataType=\"0x0005\" ObjectType=\"0x07\" Name=\"Error Register\"/>" +
                          "</register_map>" +
                      "</root>";
      
                  XDocument doc = XDocument.Parse(xml);
      
                  var results = doc.Descendants("Register").Select(x => new {
                      id = (int)x.Attribute("ID"),
                      index = int.Parse(x.Attribute("Index").Value.Substring(2), NumberStyles.HexNumber,  CultureInfo.CurrentCulture),
                      dataType = int.Parse(x.Attribute("DataType").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
                      objectType = int.Parse(x.Attribute("ObjectType").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
                      name = (string)x.Attribute("Name")
                  }).ToList();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-14
        • 1970-01-01
        • 2019-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-20
        • 2011-11-27
        相关资源
        最近更新 更多