简体   繁体   English

XML解析为列表

[英]Xml parsing into a list

I have an xml doc which I need to parse it into a generic list or even into a datatable since my ultimate goal is to show the data in a grid. 我有一个xml文档,我需要将其解析为通用列表甚至数据表,因为我的最终目标是在网格中显示数据。 I was writing LINQ queries and I got quite close but not able to get to what I wanted. 我当时在写LINQ查询,但已经很接近了,但无法达到我想要的目标。 The XML structure: XML结构:

<Datas preview="0">
    <meta>
        <inputOrder>
            <input>IPAddress</input>
            <input>name</input>
            <input>rawdata</input>
        </inputOrder>
    </meta>
    <data ID="0">
        <input k="IPAddress">
            <value>
                <text>ipaddress</text>
            </value>
        </input>
        <input k="name">
            <value>
                <text>some string</text>
            </value>
        </input>
        <input k="rawdata">
            <v xml:space="preserve" trunc="0">some data</v>
        </input>
    </data>
    <data ID="1">
        <input k="IPAddress">
            <value>
                <text>ipaddress</text>
            </value>
        </input>
        <input k="name">
            <value>
                <text>some string</text>
            </value>
        </input>
        <input k="rawdata">
            <v xml:space="preserve" trunc="0">some data</v>
        </input>
    </data>
</Datas>

My code so far: 到目前为止,我的代码:

//dataobject is my generic list
XElement xml = XElement.Load("c:\\test.xml");
var mydata = (from header in xml.Elements("data").Elements("input")
                select new dataobject
                {
                    ipaddress = ??
                    name= ??
                    rawdata=??
                }).ToList();
  1. Is there an efficient way to load the above values 是否有一种有效的方法来加载上述值
  2. I initially wanted to dynamically load the values of into a datatable column header and then add the values into it but if there is a good way of doing it without even having to convert into list please let me know 我最初想将的值动态加载到数据表列标题中,然后将值添加到其中,但是如果有一个很好的方法甚至不必转换为列表,请告诉我

You may face problems with the nesting of sets of input in sets of data . 您可能会遇到在data集中嵌套input集的问题。

The nested data should not be in the loop, but should be used as a queryable XElement, where you query for attribute names and values. 嵌套的数据不应在循环中,而应用作可查询的XElement,您可以在其中查询属性名称和值。

So something like: 所以像这样:

xml.Elements("data").Select(data =>
    new dataobject {
        ipaddress = data.FirstOrDefault(el => el.Attribute("k") != null &&
                     el.Attribute("k").Value == "IPAddress");

Complete this with the other requested fields, nice defaults, and a ToList() . 使用其他要求的字段,漂亮的默认值和ToList()完成此操作。

One possible solution could look like this: 一种可能的解决方案如下所示:

  • create a DataObject structure 创建一个DataObject结构
  • fetch all data nodes 获取所有数据节点
  • for each data node, fetch all inputs 对于每个数据节点,获取所有输入
  • read input fields and create DataObject 读取输入字段并创建DataObject
  • add DataObject to list 将DataObject添加到列表
  • use list to add objects to DB 使用列表将对象添加到数据库

The DataObject class: DataObject类:

public class DataObject
{
    public String IP { get; set; }
    public String Name { get; set; }
    public String RawData { get; set; }
}

The code to parse the document to a list of DataObject elements ( List<DataObject> ): 将文档解析为DataObject元素List<DataObject>List<DataObject> )的代码:

try
{
    var result = new List<DataObject>();
    // helper function to fetch node value regarding attribute name
    Func<List<XElement>, String, String> getValueFromAttribute = (list, attributeName) => 
    {
        var r = list.FirstOrDefault(i => i.Attribute("k").Value.ToLower() == attributeName.ToLower());
        return r != null ? r.Value : String.Empty;
    };

    var xml = XDocument.Load("d:\\temp\\input.xml");
    // fetch all DATA nodes and iterate over every one
    xml.Root.Descendants("data").ToList().ForEach(data =>
    {
        // fetch INPUT nodes
        var inputs = data.Descendants("input").ToList();
        result.Add(new DataObject
        {
            IP = getValueFromAttribute(inputs, "ipaddress"),
            Name = getValueFromAttribute(inputs, "name"),
            RawData = getValueFromAttribute(inputs, "rawdata")
        });
    });
    result.ForEach(item =>
    {
        Console.WriteLine("{0} - {1} - {2}", item.IP, item.Name, item.RawData);
    });
}
catch (Exception exception)
{
    Console.WriteLine(exception.Message);
}

I have modified the XML - every data node contains different value, so the input using the code from above is: 我已经修改了XML-每个数据节点都包含不同的值,因此使用上面代码的输入是:

1 - A - RD A
2 - B - RD B

Even if you just want to add the values directly to a database, the DataObject class (resp. the list) will help you to easily transfer the values (extract and put to DB). 即使您只想将值直接添加到数据库中,DataObject类(分别是列表)也将帮助您轻松地传输值(提取并放入DB)。

My input xml for the example: 我的输入xml示例:

<?xml version="1.0" encoding="utf-8"?>
<Datas preview="0">
    <meta>
        <inputOrder>
            <input>IPAddress</input>
            <input>name</input>
            <input>rawdata</input>
        </inputOrder>
    </meta>
    <data ID="0">
        <input k="IPAddress">
            <value>
                <text>1</text>
            </value>
        </input>
        <input k="name">
            <value>
                <text>A</text>
            </value>
        </input>
        <input k="rawdata">
            <v xml:space="preserve" trunc="0">RD A</v>
        </input>
    </data>
    <data ID="1">
        <input k="IPAddress">
            <value>
                <text>2</text>
            </value>
        </input>
        <input k="name">
            <value>
                <text>B</text>
            </value>
        </input>
        <input k="rawdata">
            <v xml:space="preserve" trunc="0">RD B</v>
        </input>
    </data>
</Datas>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM