使用 LINQ to XML 解析 xml 来类对象

发布于 2024-12-20 01:05:02 字数 913 浏览 0 评论 0原文

我有

<Model>
    <Components>
        <Component name="a" id="aaa" molarmass="60.05"/>
        <Component name="b" id="bbb" molarmass="18.02"/>
        <Component name="c" id="ccc" molarmass="32.04"/>
        <Component name="d" id="ddd" molarmass="46.03"/>
    </Components>
    ...
</Model>

public class ChemieComponent
{
    public string Name { get; set; }
    public string Id { get; set; }
    public double MolarMass { get; set; }
}

可以使用 LINQ 查询将此组件解析为对象吗?如何?我最终应该有一个 IEnumerable,对吗?

编辑

<Points>
    <Point name="P1" pressure="1">
    <Fractions>
        <Fraction id="aaa" value="0.15272159"/>
        <Fraction id="bbb" value="0.15272159"/>
    </Fractions>
    more points...
 </Points>

I have

<Model>
    <Components>
        <Component name="a" id="aaa" molarmass="60.05"/>
        <Component name="b" id="bbb" molarmass="18.02"/>
        <Component name="c" id="ccc" molarmass="32.04"/>
        <Component name="d" id="ddd" molarmass="46.03"/>
    </Components>
    ...
</Model>

and the class

public class ChemieComponent
{
    public string Name { get; set; }
    public string Id { get; set; }
    public double MolarMass { get; set; }
}

Can I with the LINQ query parse this components to objects? How? I the end should I have a IEnumerable, right?

EDIT

<Points>
    <Point name="P1" pressure="1">
    <Fractions>
        <Fraction id="aaa" value="0.15272159"/>
        <Fraction id="bbb" value="0.15272159"/>
    </Fractions>
    more points...
 </Points>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

和影子一齐双人舞 2024-12-27 01:05:02

您可以使用以下内容:

XDocument doc = XDocument.Parse(xml);
IEnumerable<ChemieComponent> result = from c in doc.Descendants("Component")
                                      select new ChemieComponent()
                                      {
                                          Name = (string)c.Attribute("name"),
                                          Id = (string)c.Attribute("id"),
                                          MolarMass = (double)c.Attribute("molarmass")
                                      };

编辑

也可以使用 Linq to Xml 访问嵌套元素:

public class Point 
{
    public string Name { get; set; }
    public int Pressure { get; set; }

    public IEnumerable<Fraction> Fractions { get; set; }
}

public class Fraction
{
    public string Id { get; set; }
    public double Value { get; set; }
}

static void Main()
{
    string xml = @"<Points>
        <Point name='P1' pressure='1'>
            <Fractions>
                <Fraction id='aaa' value='0.15272159'/>
                <Fraction id='bbb' value='0.15272159'/>
            </Fractions>
        </Point>
        </Points>";

    XDocument doc = XDocument.Parse(xml);
    IEnumerable<Point> result = from c in doc.Descendants("Point")
                                select new Point()
                                {
                                    Name = (string)c.Attribute("name"),
                                    Pressure = (int)c.Attribute("pressure"),
                                    Fractions = from f in c.Descendants("Fraction")
                                                select new Fraction() 
                                                {
                                                    Id = (string)f.Attribute("id"),
                                                    Value = (double)f.Attribute("value"),
                                                }
                                };
}

You can use the following:

XDocument doc = XDocument.Parse(xml);
IEnumerable<ChemieComponent> result = from c in doc.Descendants("Component")
                                      select new ChemieComponent()
                                      {
                                          Name = (string)c.Attribute("name"),
                                          Id = (string)c.Attribute("id"),
                                          MolarMass = (double)c.Attribute("molarmass")
                                      };

EDIT

Accessing nested elements with Linq to Xml is also possible:

public class Point 
{
    public string Name { get; set; }
    public int Pressure { get; set; }

    public IEnumerable<Fraction> Fractions { get; set; }
}

public class Fraction
{
    public string Id { get; set; }
    public double Value { get; set; }
}

static void Main()
{
    string xml = @"<Points>
        <Point name='P1' pressure='1'>
            <Fractions>
                <Fraction id='aaa' value='0.15272159'/>
                <Fraction id='bbb' value='0.15272159'/>
            </Fractions>
        </Point>
        </Points>";

    XDocument doc = XDocument.Parse(xml);
    IEnumerable<Point> result = from c in doc.Descendants("Point")
                                select new Point()
                                {
                                    Name = (string)c.Attribute("name"),
                                    Pressure = (int)c.Attribute("pressure"),
                                    Fractions = from f in c.Descendants("Fraction")
                                                select new Fraction() 
                                                {
                                                    Id = (string)f.Attribute("id"),
                                                    Value = (double)f.Attribute("value"),
                                                }
                                };
}
白昼 2024-12-27 01:05:02

我意识到这是一篇旧文章,但最近我一直在将 XML 读入对象中。我并不热衷于 Linq to XML - 它的可读性不太好,依赖于“魔术字符串”,并且如果 XML 架构发生更改,则需要更改代码。

对于任何感兴趣的人,我使用 XmlSerializer 类将 XML 反序列化为对象。将反序列化代码放入通用帮助器方法中,瞧 - 将 XML 文件反序列化为对象图的一行代码:-

using System.IO;
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        var xml = @"<?xml version='1.0' encoding='utf-8' ?>
            <Model>
                <Points>
                    <Point name='P1' pressure='1'>
                        <Fractions>
                            <Fraction id='aaa' value='0.15272159'/>
                            <Fraction id='bbb' value='0.15272159'/>
                        </Fractions>
                    </Point>
                </Points>
            </Model>";

        var model = DeserializeObject<Model>(xml);
    }

    private static T DeserializeObject<T>(string xml)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var tr = new StringReader(xml))
        {
            return (T)serializer.Deserialize(tr);
        }
    }
}

public class Model
{
    [XmlArrayItem("Point")]
    public Point[] Points { get; set; }
}

public class Point
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "pressure")]
    public int Pressure { get; set; }

    [XmlArrayItem("Fraction")]
    public Fraction[] Fractions { get; set; }
}

public class Fraction
{
    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }

    [XmlAttribute(AttributeName = "value")]
    public double Value { get; set; }
}

一些注意事项:-

该解决方案显然依赖于用 XML 属性装饰域模型,这可能或者您可能无法接受。该解决方案还依赖于 XML 中存在的外部元素,并且如果根元素是数组(本例中为 ),则该解决方案将不起作用。

不可能指定 IEnumerable<> (OP提到的);您可以使用数组或List

I realise this is an old post, but I've been doing some reading of XML into objects recently. I wasn't keen on Linq to XML - it's not very readable, relies on "magic strings", and requires code changes if the XML schema changes.

For anyone interested, I use the XmlSerializer class to deserialize the XML into objects. Put the deserialization code into a generic helper method, and voila - one-line of code to deserialize an XML file into an object graph:-

using System.IO;
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        var xml = @"<?xml version='1.0' encoding='utf-8' ?>
            <Model>
                <Points>
                    <Point name='P1' pressure='1'>
                        <Fractions>
                            <Fraction id='aaa' value='0.15272159'/>
                            <Fraction id='bbb' value='0.15272159'/>
                        </Fractions>
                    </Point>
                </Points>
            </Model>";

        var model = DeserializeObject<Model>(xml);
    }

    private static T DeserializeObject<T>(string xml)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var tr = new StringReader(xml))
        {
            return (T)serializer.Deserialize(tr);
        }
    }
}

public class Model
{
    [XmlArrayItem("Point")]
    public Point[] Points { get; set; }
}

public class Point
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "pressure")]
    public int Pressure { get; set; }

    [XmlArrayItem("Fraction")]
    public Fraction[] Fractions { get; set; }
}

public class Fraction
{
    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }

    [XmlAttribute(AttributeName = "value")]
    public double Value { get; set; }
}

A couple of caveats:-

This solution obviously relies on decorating the domain models with XML attributes, which may or may not be acceptable to you. The solution also relies on an outer element being present in the XML, and won't work if the root element is an array (<Points> in this example).

It's not possible to specify IEnumerable<> (which the OP mentioned); you can use arrays or List<>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文