如何反序列化xml文件的子节点

Posted

技术标签:

【中文标题】如何反序列化xml文件的子节点【英文标题】:How to deserialize child nodes of xml file 【发布时间】:2021-07-19 00:07:29 【问题描述】:

我使用 Xamarin android 创建了一个应用程序。计划是从 Assets 文件夹中打开 Clients.xml 的只读副本,并在内部存储中创建副本以供将来编辑。默认文件有一个客户端根节点和六个客户端子节点。

我已经完成了读取资产并创建本地文件的程度,但仅包含第一个子节点。我不能把它放到一个子节点数组中。

读取所有子节点需要做什么?

读取资产并创建本地文件。

        // Get storage path
        path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);

        // Create clients file on first build
        string filename = System.IO.Path.Combine(path, "Clients.xml");
        if (!File.Exists(filename))
        
            clients clients;

            // Load read-only asset from file
            var xmlSerialSettings = new XmlSerializer(typeof(clients));
            using (StreamReader sr = new StreamReader(Android.App.Application.Context.Assets.Open("Clients.xml"), true))
            
                clients = (clients)xmlSerialSettings.Deserialize(sr);
            
            // Save local version to edit
            var xsw = new XmlSerializer(typeof(clients));
            using (StreamWriter sw = new StreamWriter(filename, false))
            
                xsw.Serialize(sw, clients);
            
        

客户端.xml

<?xml version="1.0" encoding="utf-8" ?>
<clients>
    <client id="1">
        <name>Bob</name>
        <address>Home</address>
        <postcode>CO1</postcode>
        <email>bob@home.com</email>
        <landline></landline>
        <mobile>07784</mobile>
    </client>
    <client id="2">
        <name>...</name>
        <address>...</address>
        <postcode>...</postcode>
        <email>...</email>
        <landline>...</landline>
        <mobile>...</mobile>
    </client>
    ....
</clients>

Clients.cs

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace QuoteBuilder

    [Serializable, XmlRoot("clients")]
    public class clients
    
        [XmlElement("client")]
        public client client  get; set; 

        public clients()
        

        

        public clients(client client)
        
            this.client = client;
        
    

    public class client
    
        public string name  get; set; 
        public string address  get; set; 
        public string postcode  get; set; 
        public string email  get; set; 
        public string landline  get; set; 
        public string mobile  get; set; 

        public client()
        

        

        public client(string name, string address, string postcode, string email, string landline, string mobile)
        
            this.name = name;
            this.address = address;
            this.postcode = postcode;
            this.email = email;
            this.landline = landline;
            this.mobile = mobile;
        
    

【问题讨论】:

【参考方案1】:

在您的客户类中,您定义了一个成员 - 客户。它不是一个集合,当您将 xml 文件反序列化为客户端类时,它只反序列化一个节点(第一个)。 在里面使用 List 或其他集合:

    [Serializable, XmlRoot("clients")]
    public class Clients
    
        [XmlElement("client")]
        public List<Client> client  get; set;  // Collection

        public Clients()
        

        

        public Clients(List<Client> client)
        
            this.client = client;
        
    

类也使用 CamelCase 命名,变量使用小写命名 - 它更具可读性

【讨论】:

完美,谢谢。我一直在尝试使用 client[] 但它正在更改为修复它的列表。

以上是关于如何反序列化xml文件的子节点的主要内容,如果未能解决你的问题,请参考以下文章

GroovyXml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 删除 Xml 文件中的节点 | 增加 Xml 文件中的节点 | 将修改后的 Xml 数据输出到文件中 )

GroovyXml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 获取 Xml 文件中的节点和属性 | 获取 Xml 文件中的节点属性 )

如何将不同类型的子元素反序列化为基类型的列表/集合,这是相应类的属性

反序列化对象忽略某些节点

使用 C# Xml.Serialization 库反序列化每个重复的 XML 节点并将其映射到对象的属性

xmldecoder反序列化漏洞分析