用C#解析XML的可变子结构

用C#解析XML的可变子结构,c#,xml,linq,C#,Xml,Linq,我需要解析具有以下结构的XML文件:EDITED 1000 56700 0 D 1000 60000 37,5 37,3 37,6 D 38 如您所见,当值已知或缺失时,几个字段的描述不同。我曾尝试在数据集中使用ReadXml(),但它似乎不适用于“变量结构”。 看起来解决方案可能是使用Xdocument和LINQ,但我对LINQ一无所知,并且我没有成功地编写一个工作代码 如果有人能向我展示可能的代码来解析和打印(或者更好地添加到数据库中)这种XML文件的内容,我将不胜感激。Lin

我需要解析具有以下结构的XML文件:EDITED


1000
56700
0
D
1000
60000
37,5 
37,3 
37,6 
D
38

如您所见,当值已知或缺失时,几个字段的描述不同。我曾尝试在数据集中使用ReadXml(),但它似乎不适用于“变量结构”。 看起来解决方案可能是使用Xdocument和LINQ,但我对LINQ一无所知,并且我没有成功地编写一个工作代码


如果有人能向我展示可能的代码来解析和打印(或者更好地添加到数据库中)这种XML文件的内容,我将不胜感激。

Linq在这里没有帮助。您可以做的是使用示例xml为xml创建DTO,该示例xml包含可以在xml中返回的所有属性和节点

然后将xml反序列化为该类型

您的类将类似于上面生成的xml中的以下内容:

[XmlRoot(ElementName="min")]
public class Min {
    [XmlAttribute(AttributeName="missing")]
    public string Missing { get; set; }
}

[XmlRoot(ElementName="max")]
public class Max {
    [XmlAttribute(AttributeName="missing")]
    public string Missing { get; set; }
}

[XmlRoot(ElementName="source_code")]
public class Source_code {
    [XmlAttribute(AttributeName="missing")]
    public string Missing { get; set; }
}

[XmlRoot(ElementName="COMPO")]
public class COMPO {
    [XmlElement(ElementName="alim_code")]
    public string Alim_code { get; set; }
    [XmlElement(ElementName="const_code")]
    public string Const_code { get; set; }
    [XmlElement(ElementName="teneur")]
    public string Teneur { get; set; }
    [XmlElement(ElementName="min")]
    public Min Min { get; set; }
    [XmlElement(ElementName="max")]
    public Max Max { get; set; }
    [XmlElement(ElementName="code_confiance")]
    public string Code_confiance { get; set; }
    [XmlElement(ElementName="source_code")]
    public Source_code Source_code { get; set; }
}
现在可以使用`XmlSerializer类对其进行反序列化:

XmlSerializer serializer = new XmlSerializer(typeof(List<COMPO>));
List<COMPO> compos = null;
using (var reader = new StringReader(xml))
{
   compos = (List<COMPO>)serializer.Deserialize(reader);
}
现在,请相应地调整反序列化代码:

XmlSerializer serializer = new XmlSerializer(typeof(Table));
Table table = null;
using (var reader = new StringReader(xml))
{
   compos = (Table)serializer.Deserialize(reader);
}

Linq在这里没有帮助。您可以做的是使用示例xml为xml创建DTO,该示例xml包含可以在xml中返回的所有属性和节点

然后将xml反序列化为该类型

您的类将类似于上面生成的xml中的以下内容:

[XmlRoot(ElementName="min")]
public class Min {
    [XmlAttribute(AttributeName="missing")]
    public string Missing { get; set; }
}

[XmlRoot(ElementName="max")]
public class Max {
    [XmlAttribute(AttributeName="missing")]
    public string Missing { get; set; }
}

[XmlRoot(ElementName="source_code")]
public class Source_code {
    [XmlAttribute(AttributeName="missing")]
    public string Missing { get; set; }
}

[XmlRoot(ElementName="COMPO")]
public class COMPO {
    [XmlElement(ElementName="alim_code")]
    public string Alim_code { get; set; }
    [XmlElement(ElementName="const_code")]
    public string Const_code { get; set; }
    [XmlElement(ElementName="teneur")]
    public string Teneur { get; set; }
    [XmlElement(ElementName="min")]
    public Min Min { get; set; }
    [XmlElement(ElementName="max")]
    public Max Max { get; set; }
    [XmlElement(ElementName="code_confiance")]
    public string Code_confiance { get; set; }
    [XmlElement(ElementName="source_code")]
    public Source_code Source_code { get; set; }
}
现在可以使用`XmlSerializer类对其进行反序列化:

XmlSerializer serializer = new XmlSerializer(typeof(List<COMPO>));
List<COMPO> compos = null;
using (var reader = new StringReader(xml))
{
   compos = (List<COMPO>)serializer.Deserialize(reader);
}
现在,请相应地调整反序列化代码:

XmlSerializer serializer = new XmlSerializer(typeof(Table));
Table table = null;
using (var reader = new StringReader(xml))
{
   compos = (Table)serializer.Deserialize(reader);
}

我将使用Xml Linq。您需要正确处理一些可以为null的项。请参阅下面的代码

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
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            IFormatProvider provider = CultureInfo.InvariantCulture;

            List<Compo> compos = doc.Descendants("COMPO").Select(x => new Compo() {
                alim_code = (int?)x.Element("alim_code"),
                const_code = (int?)x.Element("const_code"),
                teneur =  (string)x.Element("teneur") == "" ? null : (decimal?)Convert.ToDecimal((string) x.Element("teneur"),provider),
                min = (string)x.Element("min") == "" ? null : (decimal?)Convert.ToDecimal((string) x.Element("teneur"),provider),
                max = (string)x.Element("max") == "" ? null : (decimal?)Convert.ToDecimal((string) x.Element("teneur"),provider),
                code_confiance = (string)x.Element("code_confiance"),
                source_code = (string)x.Element("source_code") == "" ? null : (int?)int.Parse(((string)x.Element("source_code")).Trim())
            }).ToList();
        }
    }
    public class Compo
    {
        public int? alim_code {get; set;}
        public int? const_code {get; set;}
        public decimal? teneur {get; set;}
        public decimal? min {get; set;}
        public decimal? max {get; set;}
        public string code_confiance {get; set;}
        public int? source_code { get; set; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
利用制度全球化;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
IFormatProvider=CultureInfo.InvariantCulture;
列出compos=doc.substands(“COMPO”)。选择(x=>newcompo(){
alim_代码=(int?)x.Element(“alim_代码”),
常量代码=(int?)x.Element(“常量代码”),
teneur=(字符串)x.Element(“teneur”)==“”?null:(十进制?)Convert.ToDecimal((字符串)x.Element(“teneur”),提供程序),
min=(字符串)x.Element(“min”)=“”?null:(十进制?)Convert.ToDecimal((字符串)x.Element(“teneur”),提供程序),
max=(字符串)x.Element(“max”)=“”?null:(十进制?)Convert.ToDecimal((字符串)x.Element(“teneur”),提供程序),
code_confiance=(字符串)x.Element(“code_confiance”),
source_code=(string)x.Element(“source_code”)==“null:(int?)int.Parse(((string)x.Element(“source_code”)).Trim())
}).ToList();
}
}
公共类组件
{
公共int?alim_代码{get;set;}
公共int?const_代码{get;set;}
公共十进制数?teneur{get;set;}
公共十进制数?min{get;set;}
公共小数?max{get;set;}
公共字符串代码_confiance{get;set;}
公共int?源代码{get;set;}
}
}

我会使用Xml Linq。您需要正确处理一些可以为null的项。请参阅下面的代码

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
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            IFormatProvider provider = CultureInfo.InvariantCulture;

            List<Compo> compos = doc.Descendants("COMPO").Select(x => new Compo() {
                alim_code = (int?)x.Element("alim_code"),
                const_code = (int?)x.Element("const_code"),
                teneur =  (string)x.Element("teneur") == "" ? null : (decimal?)Convert.ToDecimal((string) x.Element("teneur"),provider),
                min = (string)x.Element("min") == "" ? null : (decimal?)Convert.ToDecimal((string) x.Element("teneur"),provider),
                max = (string)x.Element("max") == "" ? null : (decimal?)Convert.ToDecimal((string) x.Element("teneur"),provider),
                code_confiance = (string)x.Element("code_confiance"),
                source_code = (string)x.Element("source_code") == "" ? null : (int?)int.Parse(((string)x.Element("source_code")).Trim())
            }).ToList();
        }
    }
    public class Compo
    {
        public int? alim_code {get; set;}
        public int? const_code {get; set;}
        public decimal? teneur {get; set;}
        public decimal? min {get; set;}
        public decimal? max {get; set;}
        public string code_confiance {get; set;}
        public int? source_code { get; set; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
利用制度全球化;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
IFormatProvider=CultureInfo.InvariantCulture;
列出compos=doc.substands(“COMPO”)。选择(x=>newcompo(){
alim_代码=(int?)x.Element(“alim_代码”),
常量代码=(int?)x.Element(“常量代码”),
teneur=(字符串)x.Element(“teneur”)==“”?null:(十进制?)Convert.ToDecimal((字符串)x.Element(“teneur”),提供程序),
min=(字符串)x.Element(“min”)=“”?null:(十进制?)Convert.ToDecimal((字符串)x.Element(“teneur”),提供程序),
max=(字符串)x.Element(“max”)=“”?null:(十进制?)Convert.ToDecimal((字符串)x.Element(“teneur”),提供程序),
code_confiance=(字符串)x.Element(“code_confiance”),
source_code=(string)x.Element(“source_code”)==“null:(int?)int.Parse(((string)x.Element(“source_code”)).Trim())
}).ToList();
}
}
公共类组件
{
公共int?alim_代码{get;set;}
公共int?const_代码{get;set;}
公共十进制数?teneur{get;set;}
公共十进制数?min{get;set;}
公共小数?max{get;set;}
公共字符串代码_confiance{get;set;}
公共int?源代码{get;set;}
}
}

基于Ehsan Sajjad提案的工作解决方案:)

[XmlRoot(ElementName=“min”)]
公共课
{
[XmlAttribute(AttributeName=“缺失”)]
公共字符串缺少{get;set;}
[XmlText]
公共字符串值{get;set;}
}
[XmlRoot(ElementName=“max”)]
公共类最大值
{
[XmlAttribute(AttributeName=“缺失”)]
公共字符串缺少{get;set;}
[XmlText]
公共字符串值{get;set;}
}
[XmlRoot(ElementName=“source_code”)]
公共类源代码
{
[XmlAttribute(AttributeName=“缺失”)]
公共字符串缺少{get;set;}
[XmlText]
公共字符串值{get;set;}
}
[XmlRoot(元素