使用 XmlSerializer,如何为列表设置元素名称?
With XmlSerializer, how to set element names for a List?
我似乎无法使 XmlSerializer 属性起作用。我有
public class DriveData
{
public string Model { get; set; }
public string Type { get; set; }
public int SizeGB { get; set; }
public string SerialNumber { get; set; }
public bool IsOK { get; set; }
}
static List<DriveData> DiskDrives { get; set; }
XmlSerializer serializer = new XmlSerializer(typeof(List<DriveData>));
FileStream xmlFile = File.Create("DiskDrives.xml");
serializer.Serialize(xmlFile, DiskDrives);
xmlFile.Close();
我想要的是:
<?xml version="1.0" encoding="utf-8" ?>
<HardDrives>
<HardDrive>
<Model>Seagate1</Model>
...
</HardDrive>
<HardDrive>
...
</HardDrive>
但我得到的是:
<?xml version="1.0"?>
<ArrayOfDriveData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DriveData>
<Model>Seagate1</Model>
<Type>SATA</Type>
<SizeGB>999</SizeGB>
...
</DriveData>
<DriveData>
...
</DriveData>
</ArrayOfDriveData>
[XmlElement(ElementName = "HardDrives")]
在我的 List<DriveData>
上什么都不做。 [XmlElement(ElementName = "HardDrive")]
在我的 DriveData
class 上导致构建错误。如何将根和 <HardDrive>
元素名称设置为我想要的名称?
虽然 XmlSerializer
可以 直接序列化一个 List<T>
,就像你用 new XmlSerializer(typeof(List<DriveData>))
做的那样,但权衡是你不能'对生成的元素的名称没有做太多。更好的方法是将列表包装成一个 class ,其属性如下:
[XmlRoot("HardDrives")]
public class DiskDrives
{
[XmlElement("HardDrive")]
public List<DriveData> Drives { get; set; }
}
[XmlRoot]
属性表示顶级文档元素,而 [XmlElement]
属性控制 属性 的序列化方式。
XmlSerializer
生成的 XML 将如下所示:
<?xml version="1.0" encoding="utf-16"?>
<HardDrives xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<HardDrive>
<Model>WD</Model>
…
</HardDrive>
<HardDrive>
<Model>Seagate</Model>
…
</HardDrive>
</HardDrives>
如果您将 List<DriveData>
嵌入到更复杂的结构中,另一种方法是使用 [XmlArray]
和 [XmlArrayItem]
属性,它们控制 IEnumerable
属性 已序列化,哪些元素名称应用于其项目。以下数据结构:
[XmlRoot("Inventory")]
public class Inventory
{
… more properties here…
[XmlArray("HardDrives")]
[XmlArrayItem("HardDrive")]
public List<DriveData> Drives { get; set; }
}
会产生这样的 XML:
<?xml version="1.0" encoding="utf-16"?>
<Inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
… more properties would be serialized here …
<HardDrives>
<HardDrive>
<Model>WD</Model>
…
</HardDrive>
<HardDrive>
<Model>Seagate</Model>
…
</HardDrive>
</HardDrives>
</Inventory>
可能有更多更好的方法来实现这一点,但这里有另一种方法。
private static void GenerateXml()
{
List<DriveData> DiskDrives = new List<DriveData>();
DiskDrives.Add(new DriveData() { Model = "model1", Type = "type1", SizeGB = 10, SerialNumber = "20155", IsOK = false });
DiskDrives.Add(new DriveData() { Model = "model2", Type = "type2", SizeGB = 20, SerialNumber = "20165", IsOK = true });
var newDoc = new XDocument(new XDeclaration("1.0", null, "yes"));
XElement xmlElements = new XElement("HardDrives",
from item in DiskDrives
select new XElement("HardDrive",
new XElement("Model", item.Model),
new XElement("Type", item.Type),
new XElement("SizeGB", item.SizeGB),
new XElement("SerialNumber", item.SerialNumber),
new XElement("IsOK", item.IsOK)));
newDoc.Add(xmlElements);
newDoc.Save(@"C:\sample.xml");
}
输出XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<HardDrives>
<HardDrive>
<Model>model1</Model>
<Type>type1</Type>
<SizeGB>10</SizeGB>
<SerialNumber>20155</SerialNumber>
<IsOK>false</IsOK>
</HardDrive>
<HardDrive>
<Model>model2</Model>
<Type>type2</Type>
<SizeGB>20</SizeGB>
<SerialNumber>20165</SerialNumber>
<IsOK>true</IsOK>
</HardDrive>
</HardDrives>
您可以保留您的模型。在创建序列化程序对象时,将 class 和第二个参数的 XmlType 属性用作新的 XmlRootAttribute("HardDrives")。
[XmlType("HardDrive")]
public class DriveData
{
public string Model { get; set; }
public string Type { get; set; }
public int SizeGB { get; set; }
public string SerialNumber { get; set; }
public bool IsOK { get; set; }
}
class Program
{
static List<DriveData> DiskDrives { get; set; } = new List<DriveData>();
static void Main(string[] args)
{
DiskDrives.Add(new DriveData { Model = "Seagate1", Type = "SATA", SizeGB = 999 });
DiskDrives.Add(new DriveData { Model = "Seagate2", Type = "SATA", SizeGB = 777 });
XmlSerializer serializer = new XmlSerializer(typeof(List<DriveData>), new XmlRootAttribute("HardDrives"));
FileStream xmlFile = File.Create("DiskDrives.xml");
serializer.Serialize(xmlFile, DiskDrives);
xmlFile.Close();
Console.Read();
}
}
我似乎无法使 XmlSerializer 属性起作用。我有
public class DriveData
{
public string Model { get; set; }
public string Type { get; set; }
public int SizeGB { get; set; }
public string SerialNumber { get; set; }
public bool IsOK { get; set; }
}
static List<DriveData> DiskDrives { get; set; }
XmlSerializer serializer = new XmlSerializer(typeof(List<DriveData>));
FileStream xmlFile = File.Create("DiskDrives.xml");
serializer.Serialize(xmlFile, DiskDrives);
xmlFile.Close();
我想要的是:
<?xml version="1.0" encoding="utf-8" ?>
<HardDrives>
<HardDrive>
<Model>Seagate1</Model>
...
</HardDrive>
<HardDrive>
...
</HardDrive>
但我得到的是:
<?xml version="1.0"?>
<ArrayOfDriveData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DriveData>
<Model>Seagate1</Model>
<Type>SATA</Type>
<SizeGB>999</SizeGB>
...
</DriveData>
<DriveData>
...
</DriveData>
</ArrayOfDriveData>
[XmlElement(ElementName = "HardDrives")]
在我的 List<DriveData>
上什么都不做。 [XmlElement(ElementName = "HardDrive")]
在我的 DriveData
class 上导致构建错误。如何将根和 <HardDrive>
元素名称设置为我想要的名称?
虽然 XmlSerializer
可以 直接序列化一个 List<T>
,就像你用 new XmlSerializer(typeof(List<DriveData>))
做的那样,但权衡是你不能'对生成的元素的名称没有做太多。更好的方法是将列表包装成一个 class ,其属性如下:
[XmlRoot("HardDrives")]
public class DiskDrives
{
[XmlElement("HardDrive")]
public List<DriveData> Drives { get; set; }
}
[XmlRoot]
属性表示顶级文档元素,而 [XmlElement]
属性控制 属性 的序列化方式。
XmlSerializer
生成的 XML 将如下所示:
<?xml version="1.0" encoding="utf-16"?>
<HardDrives xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<HardDrive>
<Model>WD</Model>
…
</HardDrive>
<HardDrive>
<Model>Seagate</Model>
…
</HardDrive>
</HardDrives>
如果您将 List<DriveData>
嵌入到更复杂的结构中,另一种方法是使用 [XmlArray]
和 [XmlArrayItem]
属性,它们控制 IEnumerable
属性 已序列化,哪些元素名称应用于其项目。以下数据结构:
[XmlRoot("Inventory")]
public class Inventory
{
… more properties here…
[XmlArray("HardDrives")]
[XmlArrayItem("HardDrive")]
public List<DriveData> Drives { get; set; }
}
会产生这样的 XML:
<?xml version="1.0" encoding="utf-16"?>
<Inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
… more properties would be serialized here …
<HardDrives>
<HardDrive>
<Model>WD</Model>
…
</HardDrive>
<HardDrive>
<Model>Seagate</Model>
…
</HardDrive>
</HardDrives>
</Inventory>
可能有更多更好的方法来实现这一点,但这里有另一种方法。
private static void GenerateXml()
{
List<DriveData> DiskDrives = new List<DriveData>();
DiskDrives.Add(new DriveData() { Model = "model1", Type = "type1", SizeGB = 10, SerialNumber = "20155", IsOK = false });
DiskDrives.Add(new DriveData() { Model = "model2", Type = "type2", SizeGB = 20, SerialNumber = "20165", IsOK = true });
var newDoc = new XDocument(new XDeclaration("1.0", null, "yes"));
XElement xmlElements = new XElement("HardDrives",
from item in DiskDrives
select new XElement("HardDrive",
new XElement("Model", item.Model),
new XElement("Type", item.Type),
new XElement("SizeGB", item.SizeGB),
new XElement("SerialNumber", item.SerialNumber),
new XElement("IsOK", item.IsOK)));
newDoc.Add(xmlElements);
newDoc.Save(@"C:\sample.xml");
}
输出XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<HardDrives>
<HardDrive>
<Model>model1</Model>
<Type>type1</Type>
<SizeGB>10</SizeGB>
<SerialNumber>20155</SerialNumber>
<IsOK>false</IsOK>
</HardDrive>
<HardDrive>
<Model>model2</Model>
<Type>type2</Type>
<SizeGB>20</SizeGB>
<SerialNumber>20165</SerialNumber>
<IsOK>true</IsOK>
</HardDrive>
</HardDrives>
您可以保留您的模型。在创建序列化程序对象时,将 class 和第二个参数的 XmlType 属性用作新的 XmlRootAttribute("HardDrives")。
[XmlType("HardDrive")]
public class DriveData
{
public string Model { get; set; }
public string Type { get; set; }
public int SizeGB { get; set; }
public string SerialNumber { get; set; }
public bool IsOK { get; set; }
}
class Program
{
static List<DriveData> DiskDrives { get; set; } = new List<DriveData>();
static void Main(string[] args)
{
DiskDrives.Add(new DriveData { Model = "Seagate1", Type = "SATA", SizeGB = 999 });
DiskDrives.Add(new DriveData { Model = "Seagate2", Type = "SATA", SizeGB = 777 });
XmlSerializer serializer = new XmlSerializer(typeof(List<DriveData>), new XmlRootAttribute("HardDrives"));
FileStream xmlFile = File.Create("DiskDrives.xml");
serializer.Serialize(xmlFile, DiskDrives);
xmlFile.Close();
Console.Read();
}
}