C#中XML与XSD文件的创建与验证

在C#开发过程中,经常需要将对象序列化为XML文件,或者从已有的XML文件生成XSD(XML Schema Definition)文件,以及验证XML文件是否符合XSD定义的规则。本文将详细介绍这三个过程的实现方法。

1. 从C#对象创建XML文件

假设有以下C#对象,希望将它们序列化为XML。

public class OrderList { public List<Order> Orders { get; set; } } public class Order { public OrderSummary OrderSummary { get; set; } public Customer Customer { get; set; } } public class Address { public string AddressLine1 { get; set; } public string AddressLine2 { get; set; } public string AddressLine3 { get; set; } public string City { get; set; } public string County { get; set; } public string PostCode { get; set; } } public class Customer { public string Title { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string Phone { get; set; } } public class OrderSummary { public List<OrderLine> OrderLines { get; set; } public Address DeliveryAddress { get; set; } public DateTime DeliveryDate { get; set; } } public class OrderLine { public decimal ItemQuanity { get; set; } public string ItemName { get; set; } }

要将这些对象保存为XML文件,可以使用以下代码:

public static void CreateXmlFile(string filename) { Address add = new Address { AddressLine1 = "AddressLine1", AddressLine2 = "AddressLine2", AddressLine3 = "AddressLine3", City = "City", County = "County", PostCode = "PostCode" }; Customer cust = new Customer { Email = "Email", FirstName = "John", LastName = "Barnes", Phone = "13311", Title = "Mr" }; OrderList orders = new OrderList(); var orderSummary = new OrderSummary { DeliveryAddress = add, DeliveryDate = DateTime.Now, OrderLines = new List<OrderLine> { new OrderLine { ItemQuanity = 150, ItemName = "TestItem1" }, new OrderLine { ItemQuanity = 250, ItemName = "TestItem2" }, new OrderLine { ItemQuanity = 4, ItemName = "TestItem3" }, }, }; Order order1 = new Order(); order1.Customer = cust; order1.OrderSummary = orderSummary; orders.Orders.Add(order1); XmlSerializer xmlSerializer = new XmlSerializer(typeof(OrderList)); using (FileStream stream = File.OpenWrite(filename)) { xmlSerializer.Serialize(stream, orders); } }

以上代码将C#对象序列化为XML文件并保存到磁盘上。

2. 从XML文件生成XSD文件

有多种方法可以从XML文件生成XSD文件,这里选择使用C#编程方式生成XSD文件。

public static void CreateSchemaFromXml(string fileName) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(OrderList)); XmlSchemas schemas = new XmlSchemas(); XmlSchemaExporter exporter = new XmlSchemaExporter(schemas); XmlTypeMapping mapping = new XmlReflectionImporter().ImportTypeMapping(typeof(OrderList)); exporter.ExportTypeMapping(mapping); var schemasData = TrimSchema(schemas); using (FileStream stream = File.OpenWrite(fileName)) { schemasData.First().Write(stream); } } private static List<XmlSchema> TrimSchema(XmlSchemas schemas) { List<XmlSchema> schemasData = new List<XmlSchema>( schemas.Where(s => s.TargetNamespace != "http://www.w3.org/2001/XMLSchema" && s.TargetNamespace != "http://microsoft.com/wsdl/types/") ); return schemasData; }

以上代码将生成一个有效的XSD文件,可以对其进行修改以添加更多的限制。

3. 使用C#验证XML文件是否符合XSD文件定义的规则

使用以下测试代码可以轻松实现XML文件的验证

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using System.Xml.Schema; using NUnit.Framework; namespace XmlTests { [TestFixture] public class StaticXmlFileTests { [TestCase(@"\Xml\BadAgainstSchema\OrdersBADExampleFileNoOrderSummary.xml", false)] [TestCase(@"\Xml\BadAgainstSchema\OrdersBADExampleFile_AddressLineTooLong.xml", false)] [TestCase(@"\Xml\Good\OrdersGOODExampleFile_FullFeatureSet.xml", true)] [TestCase(@"\Xml\Good\OrdersGOODExampleFile_MultipleOrderLines.xml", true)] [TestCase(@"\Xml\Good\OrdersGOODExampleFile_MultipleOrders.xml", true)] [TestCase(@"\Xml\Good\OrdersGOODExampleFile_SingleOrder.xml", true)] [TestCase(@"\Xml\Good\OrdersGOODExampleFile_SingleOrderLine.xml", true)] public void TestFileProducesExpectedSchemaValidationResult(string filename, bool exepectedValidationResult) { var xmlFile = ObtainFullFilePath(filename); var xsdFile = ObtainFullFilePath(@"\Xml\OrdersExampleFile.xsd"); var xdoc = XDocument.Load(xmlFile); var schemas = new XmlSchemaSet(); using (FileStream stream = File.OpenRead(xsdFile)) { schemas.Add(XmlSchema.Read(stream, (s, e) => { var x = e.Message; })); } bool isvalid = true; StringBuilder sb = new StringBuilder(); try { xdoc.Validate(schemas, (s, e) => { isvalid = false; sb.AppendLine(string.Format("Line : {0}, Message : {1}", e.Exception.LineNumber, e.Exception.Message)); }); } catch (XmlSchemaValidationException) { isvalid = false; } var validationErrors = sb.ToString(); Assert.AreEqual(exepectedValidationResult, isvalid); if (exepectedValidationResult) { Assert.AreEqual(string.Empty, validationErrors); } else { Assert.AreNotEqual(string.Empty, validationErrors); } } private string ObtainFullFilePath(string fileName) { var path = TestContext.CurrentContext.TestDirectory; return string.Format("{0}{1}", path, fileName); } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485