.NET中如何将XML内InstallmentList的OtsInstallmentsDetails转为实体列表
在.NET环境中如何将XML里InstallmentList节点下的OtsInstallmentsDetails元素转换为实体列表?
你的原代码通过硬编码节点索引定位目标元素,这种方式依赖固定的XML结构,一旦结构变动就会失效。下面提供两种更健壮、易维护的实现方案:
一、使用XPath+XmlDocument改进(兼容原代码风格)
先定义实体类(假设你已具备,这里补充完整):
public class OtsInstallment { public string SubscriberNumber { get; set; } public string SubscriberName { get; set; } public DateTime InvoiceDate { get; set; } public string InvoiceNumber { get; set; } public string InstallmentExplanation { get; set; } public int InstallmentSeqNumber { get; set; } public DateTime PaymentDate { get; set; } public decimal PaymentAmount { get; set; } public decimal InstallmentAmount { get; set; } }
改进后的解析代码:
string xmlData = result; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlData); // 配置命名空间管理器,处理XML中的命名空间 XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlDoc.NameTable); nsManager.AddNamespace("fsm", "http://FSM"); // 父节点的命名空间 // 用XPath直接定位所有OtsInstallmentsDetails节点,无需依赖硬索引 XmlNodeList installmentNodes = xmlDoc.SelectNodes( "//fsm:ControlApplicationsResponse/fsm:ControlApplicationsResult/InstallmentList/OtsInstallmentsDetails", nsManager ); List<OtsInstallment> installments = new List<OtsInstallment>(); foreach (XmlNode node in installmentNodes) { // 建议用TryParse处理类型转换,避免格式错误抛出异常 if (DateTime.TryParse(node.SelectSingleNode("InvoiceDate").InnerText, out DateTime invoiceDate) && int.TryParse(node.SelectSingleNode("InstallmentSeqNumber").InnerText, out int seqNumber) && DateTime.TryParse(node.SelectSingleNode("PaymentDate").InnerText, out DateTime paymentDate) && decimal.TryParse(node.SelectSingleNode("PaymentAmount").InnerText, out decimal paymentAmount) && decimal.TryParse(node.SelectSingleNode("InstallmentAmount").InnerText, out decimal installmentAmount)) { installments.Add(new OtsInstallment { SubscriberNumber = node.SelectSingleNode("SubscriberNumber").InnerText, SubscriberName = node.SelectSingleNode("SubscriberName").InnerText, InvoiceDate = invoiceDate, InvoiceNumber = node.SelectSingleNode("InvoiceNumber").InnerText, InstallmentExplanation = node.SelectSingleNode("InstallmentExplanation").InnerText, InstallmentSeqNumber = seqNumber, PaymentDate = paymentDate, PaymentAmount = paymentAmount, InstallmentAmount = installmentAmount }); } }
二、使用XmlSerializer自动序列化(更简洁)
通过特性配置实体类与XML节点的映射:
[XmlRoot(Namespace = "")] public class OtsInstallment { public string SubscriberNumber { get; set; } public string SubscriberName { get; set; } public DateTime InvoiceDate { get; set; } public string InvoiceNumber { get; set; } public string InstallmentExplanation { get; set; } public int InstallmentSeqNumber { get; set; } public DateTime PaymentDate { get; set; } public decimal PaymentAmount { get; set; } public decimal InstallmentAmount { get; set; } } [XmlRoot(Namespace = "")] public class InstallmentListWrapper { [XmlElement("OtsInstallmentsDetails")] public List<OtsInstallment> Installments { get; set; } }
序列化解析代码:
string xmlData = result; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlData); XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlDoc.NameTable); nsManager.AddNamespace("fsm", "http://FSM"); // 提取InstallmentList节点的XML内容 XmlNode installmentListNode = xmlDoc.SelectSingleNode( "//fsm:ControlApplicationsResponse/fsm:ControlApplicationsResult/InstallmentList", nsManager ); // 自动序列化到实体列表 XmlSerializer serializer = new XmlSerializer(typeof(InstallmentListWrapper)); using (StringReader reader = new StringReader(installmentListNode.OuterXml)) { var wrapper = (InstallmentListWrapper)serializer.Deserialize(reader); List<OtsInstallment> installments = wrapper.Installments; }
注意事项
- 类型转换优先使用
TryParse系列方法,避免因XML内容格式错误导致程序崩溃; - XML节点名称与实体类属性名称需严格匹配(大小写敏感),若名称不一致可通过
[XmlElement("节点名称")]特性指定; - 若XML存在多命名空间,必须通过
XmlNamespaceManager正确配置才能用XPath定位节点。
内容的提问来源于stack exchange,提问作者Hasan
相关产品推荐
相关产品推荐

