UBL 2.1 XML发票InvoiceLine节点C#反序列化及遍历提取问题
解决UBL 2.1发票XML反序列化中重复InvoiceLine节点的问题
1. 修正实体类的InvoiceLine定义
Visual Studio「Paste Xml as classes」工具生成的类通常不会自动标记重复节点为列表,需手动调整InvoiceLine的属性,添加对应UBL命名空间的[XmlArray]和[XmlArrayItem]特性:
public class Invoice { // 保留其他已生成字段... [XmlArray("InvoiceLine", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2")] [XmlArrayItem("InvoiceLine", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2", IsNullable = false)] public List<InvoiceLine> InvoiceLineList { get; set; } } // 对应InvoiceLine及子元素类示例(确保命名空间正确) public class InvoiceLine { [XmlElement("ID", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")] public string ID { get; set; } [XmlElement("InvoicedQuantity", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")] public decimal InvoicedQuantity { get; set; } [XmlElement("LineExtensionAmount", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")] public decimal LineExtensionAmount { get; set; } [XmlElement("Item", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2")] public Item Item { get; set; } [XmlElement("Price", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2")] public Price Price { get; set; } [XmlElement("BaseQuantity", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")] public decimal BaseQuantity { get; set; } } public class Item { [XmlElement("Name", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")] public string Name { get; set; } } public class Price { [XmlElement("PriceAmount", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")] public decimal PriceAmount { get; set; } }
2. 修正反序列化的根节点命名空间
错误提示<DocumentEnvelope xmlns='urn:eFaktura:MinFinrs:envelop:schema'>未被预期,说明根节点命名空间不匹配,需修正DocumentEnvelope类的[XmlRoot]特性:
[XmlRoot(ElementName = "DocumentEnvelope", Namespace = "urn:eFaktura:MinFinrs:envelop:schema")] public class DocumentEnvelope { [XmlElement("Invoice", Namespace = "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2")] public Invoice Invoice { get; set; } }
3. 反序列化并遍历InvoiceLine列表
使用修正后的类完成反序列化,遍历列表提取目标字段:
// 读取XML文件内容 string xmlContent = File.ReadAllText("your-invoice.xml"); // 创建XmlSerializer实例 XmlSerializer serializer = new XmlSerializer(typeof(DocumentEnvelope)); using (StringReader reader = new StringReader(xmlContent)) { var envelope = (DocumentEnvelope)serializer.Deserialize(reader); // 遍历每个InvoiceLine并输出 for (int i = 0; i < envelope.Invoice.InvoiceLineList.Count; i++) { var line = envelope.Invoice.InvoiceLineList[i]; Console.WriteLine($"第{i+1}循环:"); Console.WriteLine($"ID: {line.ID}"); Console.WriteLine($"InvoicedQuantity: {line.InvoicedQuantity}"); Console.WriteLine($"LineExtensionAmount: {line.LineExtensionAmount}"); Console.WriteLine($"Item.Name: {line.Item.Name}"); Console.WriteLine($"Price.PriceAmount: {line.Price.PriceAmount}"); Console.WriteLine($"BaseQuantity: {line.BaseQuantity}"); Console.WriteLine(); } }
关键注意事项
- 所有UBL相关节点必须指定正确的命名空间:
- 基础组件:
urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2 - 聚合组件:
urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 - 发票根节点:
urn:oasis:names:specification:ubl:schema:xsd:Invoice-2
- 基础组件:
- 重复节点必须定义为
List<T>类型,避免反序列化时丢失数据。
内容的提问来源于stack exchange,提问作者Mladen
相关产品推荐
相关产品推荐

