将 xml 个嵌套项转换为 C# 模型
convert xml nested items to c# model
我有 xml 这样的 :
<Root>
<Products>
<Product>
<ProductCode>1</ProductCode>
<Properties no="45">
<ColorProperties>
<Color>Blue</Color>
</ColorProperties>
</Properties>
</Product>
<Product>
<ProductCode>2</ProductCode>
<Properties no="45">
<ColorProperties>
<Color>Red</Color>
</ColorProperties>
</Properties>
</Product>
<Product>
<ProductCode>3</ProductCode>
<Properties no="45">
<ColorProperties>
<Color>Yellow</Color>
</ColorProperties>
</Properties>
</Product>
</Products>
</Root>
我想转换为产品模型,
class Product
{
//must be filled
}
产品顶部必须有我的属性 class 说产品属于产品,产品属于根。
我该怎么做?
我的英语不是很好很抱歉:)。
所以我不想创建 Root 和 Products 类(我认为必须有多个 [XmlRoot]),我想用 [XmlArray] 和 [XmlArrayItem] 装饰属性(及其嵌套属性)但我做不到。
如何使用 c# 将此 xml 转换为产品 class?
您可以使用 Visual Studio 的特殊粘贴魔法(编辑 - 特殊粘贴 - 粘贴为 XML)class 将任何实体搭建到 POCO class
我正是这样做的,以使用您的 XML 文件生成您的实体 classes。
现在,假设我们有以下实体 classes :
using System;
using System.ComponentModel;
using System.Xml.Serialization;
namespace XmlToClass
{
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public partial class Root
{
private RootProduct[] productsField;
[XmlArrayItem("Product", IsNullable = false)]
public RootProduct[] Products
{
get
{
return this.productsField;
}
set
{
this.productsField = value;
}
}
}
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class RootProduct
{
private byte productCodeField;
private RootProductProperties propertiesField;
public byte ProductCode
{
get
{
return this.productCodeField;
}
set
{
this.productCodeField = value;
}
}
public RootProductProperties Properties
{
get
{
return this.propertiesField;
}
set
{
this.propertiesField = value;
}
}
}
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class RootProductProperties
{
private RootProductPropertiesColorProperties colorPropertiesField;
private byte noField;
public RootProductPropertiesColorProperties ColorProperties
{
get
{
return this.colorPropertiesField;
}
set
{
this.colorPropertiesField = value;
}
}
[XmlAttribute()]
public byte no
{
get
{
return this.noField;
}
set
{
this.noField = value;
}
}
}
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class RootProductPropertiesColorProperties
{
private string colorField;
/// <remarks/>
public string Color
{
get
{
return this.colorField;
}
set
{
this.colorField = value;
}
}
}
}
只需使用通用方法添加此助手 class :
public class XmlToEntity
{
public T FromXml<T>(String xml)
{
T returnedXmlClass = default(T);
try
{
using (TextReader reader = new StringReader(xml))
{
try
{
returnedXmlClass =
(T)new XmlSerializer(typeof(T)).Deserialize(reader);
}
catch (InvalidOperationException)
{
// String passed is not XML, simply return defaultXmlClass
}
}
}
catch (Exception ex)
{
}
return returnedXmlClass;
}
}
然后在您的控制台中尝试此操作:
static void Main(string[] args)
{
var conv = new XmlToEntity();
Root root = conv.FromXml<Root>(File.ReadAllText("data.xml"));
Console.WriteLine(root.Products.Length.ToString());
}
注:
如果您希望使用不同的查询,您可以使用匿名类型和一点 LINQ,如下所示:
var query = root.Products.Select(x => new
{
ProductCode = x.ProductCode,
ProductColor = x.Properties.ColorProperties.Color,
});
您可以尝试 Cinchoo ETL - 一个开源库,以简化的方式反序列化 xml 中的选定节点。
首先用 xpath 定义 POCO class 以从产品节点中提取子节点
public class Product
{
public int ProductCode { get; set; }
[ChoXPath("Properties/@no")]
public int PropertyNo { get; set; }
[ChoXPath("Properties/ColorProperties/Color")]
public string Color { get; set; }
}
然后使用 ChoXmlReader 从 xml 加载产品节点,如下所示
using (var r = ChoXmlReader<Product>.LoadText(xml)
.WithXPath("//Product")
)
{
r.Print();
}
输出:
-- Program+Product State --
ProductCode: 1
PropertyNo: 45
Color: Blue
-- Program+Product State --
ProductCode: 2
PropertyNo: 45
Color: Red
-- Program+Product State --
ProductCode: 3
PropertyNo: 45
Color: Yellow
示例 fiddle:https://dotnetfiddle.net/uBzXpt
我有 xml 这样的 :
<Root>
<Products>
<Product>
<ProductCode>1</ProductCode>
<Properties no="45">
<ColorProperties>
<Color>Blue</Color>
</ColorProperties>
</Properties>
</Product>
<Product>
<ProductCode>2</ProductCode>
<Properties no="45">
<ColorProperties>
<Color>Red</Color>
</ColorProperties>
</Properties>
</Product>
<Product>
<ProductCode>3</ProductCode>
<Properties no="45">
<ColorProperties>
<Color>Yellow</Color>
</ColorProperties>
</Properties>
</Product>
</Products>
</Root>
我想转换为产品模型,
class Product
{
//must be filled
}
产品顶部必须有我的属性 class 说产品属于产品,产品属于根。
我该怎么做?
我的英语不是很好很抱歉:)。
所以我不想创建 Root 和 Products 类(我认为必须有多个 [XmlRoot]),我想用 [XmlArray] 和 [XmlArrayItem] 装饰属性(及其嵌套属性)但我做不到。
如何使用 c# 将此 xml 转换为产品 class?
您可以使用 Visual Studio 的特殊粘贴魔法(编辑 - 特殊粘贴 - 粘贴为 XML)class 将任何实体搭建到 POCO class
我正是这样做的,以使用您的 XML 文件生成您的实体 classes。
现在,假设我们有以下实体 classes :
using System;
using System.ComponentModel;
using System.Xml.Serialization;
namespace XmlToClass
{
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public partial class Root
{
private RootProduct[] productsField;
[XmlArrayItem("Product", IsNullable = false)]
public RootProduct[] Products
{
get
{
return this.productsField;
}
set
{
this.productsField = value;
}
}
}
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class RootProduct
{
private byte productCodeField;
private RootProductProperties propertiesField;
public byte ProductCode
{
get
{
return this.productCodeField;
}
set
{
this.productCodeField = value;
}
}
public RootProductProperties Properties
{
get
{
return this.propertiesField;
}
set
{
this.propertiesField = value;
}
}
}
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class RootProductProperties
{
private RootProductPropertiesColorProperties colorPropertiesField;
private byte noField;
public RootProductPropertiesColorProperties ColorProperties
{
get
{
return this.colorPropertiesField;
}
set
{
this.colorPropertiesField = value;
}
}
[XmlAttribute()]
public byte no
{
get
{
return this.noField;
}
set
{
this.noField = value;
}
}
}
[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class RootProductPropertiesColorProperties
{
private string colorField;
/// <remarks/>
public string Color
{
get
{
return this.colorField;
}
set
{
this.colorField = value;
}
}
}
}
只需使用通用方法添加此助手 class :
public class XmlToEntity
{
public T FromXml<T>(String xml)
{
T returnedXmlClass = default(T);
try
{
using (TextReader reader = new StringReader(xml))
{
try
{
returnedXmlClass =
(T)new XmlSerializer(typeof(T)).Deserialize(reader);
}
catch (InvalidOperationException)
{
// String passed is not XML, simply return defaultXmlClass
}
}
}
catch (Exception ex)
{
}
return returnedXmlClass;
}
}
然后在您的控制台中尝试此操作:
static void Main(string[] args)
{
var conv = new XmlToEntity();
Root root = conv.FromXml<Root>(File.ReadAllText("data.xml"));
Console.WriteLine(root.Products.Length.ToString());
}
注:
如果您希望使用不同的查询,您可以使用匿名类型和一点 LINQ,如下所示:
var query = root.Products.Select(x => new
{
ProductCode = x.ProductCode,
ProductColor = x.Properties.ColorProperties.Color,
});
您可以尝试 Cinchoo ETL - 一个开源库,以简化的方式反序列化 xml 中的选定节点。
首先用 xpath 定义 POCO class 以从产品节点中提取子节点
public class Product
{
public int ProductCode { get; set; }
[ChoXPath("Properties/@no")]
public int PropertyNo { get; set; }
[ChoXPath("Properties/ColorProperties/Color")]
public string Color { get; set; }
}
然后使用 ChoXmlReader 从 xml 加载产品节点,如下所示
using (var r = ChoXmlReader<Product>.LoadText(xml)
.WithXPath("//Product")
)
{
r.Print();
}
输出:
-- Program+Product State --
ProductCode: 1
PropertyNo: 45
Color: Blue
-- Program+Product State --
ProductCode: 2
PropertyNo: 45
Color: Red
-- Program+Product State --
ProductCode: 3
PropertyNo: 45
Color: Yellow
示例 fiddle:https://dotnetfiddle.net/uBzXpt