基于XSD填充XML对象数据并导出XML文件的技术求助
如何基于Agresso的ABWInvoice XSD生成并填充XML数据
我完全懂你的困扰——网上搜的示例要么只给个空架子的序列化代码,要么跑起来各种报错。既然你已经用xsd.exe成功生成了ABWInvoice的对应类,那接下来的关键就是正确填充对象数据再序列化,我给你一套能落地的步骤和代码:
第一步:实例化并填充ABWInvoice对象
XSD生成的复杂类型类里,很多嵌套的子对象(比如客户信息、发票行项目)都需要先实例化,不能直接给子属性赋值,否则会触发空引用异常。下面是贴合ABWInvoice结构的示例(你可以根据生成的类的实际属性名调整):
// 实例化根对象ABWInvoice var abwInvoice = new ABWInvoice(); // 填充根节点基础属性 abwInvoice.InvoiceNumber = "INV-2024-0001"; abwInvoice.InvoiceDate = DateTime.Now; abwInvoice.CurrencyCode = "CNY"; abwInvoice.TotalAmount = 1500.00M; // 填充嵌套的客户信息(假设XSD生成了CustomerType类) abwInvoice.Customer = new CustomerType(); abwInvoice.Customer.CustomerId = "CUST-0001"; abwInvoice.Customer.Name = "ABC贸易有限公司"; // 继续填充客户地址(嵌套的AddressType) abwInvoice.Customer.Address = new AddressType(); abwInvoice.Customer.Address.Street = "科技园路1号"; abwInvoice.Customer.Address.City = "深圳市"; abwInvoice.Customer.Address.PostalCode = "518000"; // 填充发票行项目(如果是数组/集合类型) abwInvoice.InvoiceLines = new InvoiceLineType[2]; // 第一行项目 abwInvoice.InvoiceLines[0] = new InvoiceLineType(); abwInvoice.InvoiceLines[0].LineNumber = 1; abwInvoice.InvoiceLines[0].ItemCode = "SOFT-001"; abwInvoice.InvoiceLines[0].Description = "企业版软件授权"; abwInvoice.InvoiceLines[0].Quantity = 1; abwInvoice.InvoiceLines[0].UnitPrice = 1200.00M; // 第二行项目 abwInvoice.InvoiceLines[1] = new InvoiceLineType(); abwInvoice.InvoiceLines[1].LineNumber = 2; abwInvoice.InvoiceLines[1].ItemCode = "SVC-001"; abwInvoice.InvoiceLines[1].Description = "年度技术支持服务"; abwInvoice.InvoiceLines[1].Quantity = 1; abwInvoice.InvoiceLines[1].UnitPrice = 300.00M;
小提示:打开你用xsd.exe生成的类文件,查看每个属性的类型——如果是类类型(比如
CustomerType),必须先new出来再赋值子属性;如果是值类型或字符串,直接赋值即可。
第二步:序列化对象到XML文件
用.NET内置的XmlSerializer完成序列化,一定要注意指定正确的命名空间(和XSD及生成类的命名空间一致),否则生成的XML会不符合Agresso的Schema要求:
using System.Xml.Serialization; using System.IO; // 从生成的ABWInvoice类的XmlRoot特性中获取命名空间 // 比如类上面会有 [XmlRoot(Namespace = "http://services.agresso.com/schema/ABWInvoice/2011/11/14")] var serializer = new XmlSerializer(typeof(ABWInvoice), "http://services.agresso.com/schema/ABWInvoice/2011/11/14"); // 写入到本地XML文件 var outputPath = @"C:\YourPath\ABW_Exported_Invoice.xml"; using (var writer = new StreamWriter(outputPath)) { serializer.Serialize(writer, abwInvoice); } // 如果要先在控制台查看生成的XML(调试用) using (var ms = new MemoryStream()) { serializer.Serialize(ms, abwInvoice); ms.Position = 0; using (var sr = new StreamReader(ms)) { Console.WriteLine("生成的XML内容:"); Console.WriteLine(sr.ReadToEnd()); } }
关键注意事项
- 核对命名空间:必须和生成类的
XmlRoot特性里的Namespace值完全一致,否则XML的根元素会缺少正确的命名空间,无法通过Agresso的Schema校验。 - 处理可选元素:XSD中标记为
minOccurs="0"的元素,你可以不用实例化赋值,序列化时会自动忽略,不会报错。 - 调试排错:如果序列化时报错,优先检查:
- 是否有嵌套对象未实例化导致的空引用异常
- 属性值类型是否匹配(比如把字符串赋值给数字类型属性)
- 是否有必填元素(
minOccurs="1")未赋值
内容的提问来源于stack exchange,提问作者BOR15K
相关产品推荐
相关产品推荐

