C# xml文檔反序列化記事

来源:https://www.cnblogs.com/hrx521/p/18215279
-Advertisement-
Play Games

可以使用XmlSerializer直接序列化和反序列化xml 反序列化如以下代碼 private T? XmlDeseriallize<T>(string filePath) { XmlSerializer serializer = new XmlSerializer(typeof(T)); usi ...


可以使用XmlSerializer直接序列化和反序列化xml

反序列化如以下代碼
        private T? XmlDeseriallize<T>(string filePath)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var xmlReader = System.Xml.XmlReader.Create(fileStream);
                var deserializedObject = (T?)serializer.Deserialize(xmlReader);
                return deserializedObject;
            }
        }
調用方法
var udidEntity = XmlDeseriallize<udid>(filePath)
其中,xml文件內容示例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<udid version="1.0">
    <header frequency="daily" id="20240520235039" type="DELTA_INCREMENTAL">
        <downloadFilePart>1</downloadFilePart>
        <downloadFileTotalParts>1</downloadFileTotalParts>
        <numberRkeyecordXML>3480</numberRkeyecordXML>
        <numberRecordsDatabase>3480</numberRecordsDatabase>
        <creationDate>2024-05-20 23:50:39</creationDate>
    </header>
    <devices>
        <device>
            <zxxsdycpbs>06974652782710</zxxsdycpbs>
            <cpbsbmtxmc>GS1</cpbsbmtxmc>
            <cpbsfbrq>2024-05-20</cpbsfbrq>
            <zxxsdyzsydydsl>1</zxxsdyzsydydsl>
            <sydycpbs></sydycpbs>
            <bszt>一維碼</bszt>
            <sfyzcbayz>是</sfyzcbayz>
            <zcbacpbs></zcbacpbs>
            <sfybtzjbs>否</sfybtzjbs>
            <btcpbsyzxxsdycpbssfyz></btcpbsyzxxsdycpbssfyz>
            <btcpbs></btcpbs>
            <cpmctymc>一次性使用吸引活檢針及附件</cpmctymc>
            <spmc></spmc>
            <ggxh>CLA2505</ggxh>
            <sfwblztlcp>否</sfwblztlcp>
            <cpms>吸引活檢針25G×50mm</cpms>
            <cphhhbh>202710</cphhhbh>
            <yflbm></yflbm>
            <qxlb>器械</qxlb>
            <flbm>14-01-09</flbm>
            <tyshxydm>91430300MA4RGKD89R</tyshxydm>
            <zczbhhzbapzbh>湘械註準20222141907</zczbhhzbapzbh>
            <ylqxzcrbarmc>湖南省拓川醫療科技有限公司</ylqxzcrbarmc>
            <ylqxzcrbarywmc></ylqxzcrbarywmc>
            <ybbm>C01060200700003149010000032</ybbm>
            <cplb>耗材</cplb>
            <cgzmraqxgxx>說明書或標簽上面不包含MR安全性信息</cgzmraqxgxx>
            <sfbjwycxsy>是</sfbjwycxsy>
            <zdcfsycs></zdcfsycs>
            <sfwwjbz>是</sfwwjbz>
            <syqsfxyjxmj>否</syqsfxyjxmj>
            <mjfs></mjfs>
            <qtxxdwzlj></qtxxdwzlj>
            <tsrq></tsrq>
            <scbssfbhph>是</scbssfbhph>
            <scbssfbhxlh>否</scbssfbhxlh>
            <scbssfbhscrq>是</scbssfbhscrq>
            <scbssfbhsxrq>是</scbssfbhsxrq>
            <tscchcztj>本產品應貯存在通風良好、無腐蝕性氣體、清潔的環境內。儲存溫度範圍為0℃至30℃,相對濕度不超過85%。本產品應使用無腐蝕性氣體、對產品無污染的運輸工具運輸,嚴禁日曬雨淋,搬運時應註意防止包裝破損。</tscchcztj>
            <tsccsm></tsccsm>
            <deviceRecordKey>069746527827102024042904331816</deviceRecordKey>
            <versionNumber>1</versionNumber>
            <versionTime>2024-05-20</versionTime>
            <versionStauts>新增</versionStauts>
            <correctionNumber>0</correctionNumber>
            <correctionRemark></correctionRemark>
            <correctionTime></correctionTime>
        </device>
        <device>
            <zxxsdycpbs>06931450103406</zxxsdycpbs>
            <cpbsbmtxmc>GS1</cpbsbmtxmc>
            <cpbsfbrq>2024-05-20</cpbsfbrq>
            <zxxsdyzsydydsl>1</zxxsdyzsydydsl>
            <sydycpbs></sydycpbs>
            <bszt>一維碼,二維碼,RFID</bszt>
            <sfyzcbayz>是</sfyzcbayz>
            <zcbacpbs></zcbacpbs>
            <sfybtzjbs>否</sfybtzjbs>
            <btcpbsyzxxsdycpbssfyz></btcpbsyzxxsdycpbssfyz>
            <btcpbs></btcpbs>
            <cpmctymc>定製式活動義齒</cpmctymc>
            <spmc></spmc>
            <ggxh>鈷鉻鉬支架可摘全口義齒 1402040900</ggxh>
            <sfwblztlcp>否</sfwblztlcp>
            <cpms>由合成樹脂牙、卡環、樹脂基托及連接體組成</cpms>
            <cphhhbh></cphhhbh>
            <yflbm></yflbm>
            <qxlb>器械</qxlb>
            <flbm>17-06-04</flbm>
            <tyshxydm>91441900675189913A</tyshxydm>
            <zczbhhzbapzbh>粵械註準20152171212</zczbhhzbapzbh>
            <ylqxzcrbarmc>東莞市帕菲克義齒科技有限公司</ylqxzcrbarmc>
            <ylqxzcrbarywmc></ylqxzcrbarywmc>
            <ybbm></ybbm>
            <cplb>耗材</cplb>
            <cgzmraqxgxx>說明書或標簽上面不包含MR安全性信息</cgzmraqxgxx>
            <sfbjwycxsy>否</sfbjwycxsy>
            <zdcfsycs></zdcfsycs>
            <sfwwjbz>否</sfwwjbz>
            <syqsfxyjxmj>否</syqsfxyjxmj>
            <mjfs></mjfs>
            <qtxxdwzlj></qtxxdwzlj>
            <tsrq></tsrq>
            <scbssfbhph>是</scbssfbhph>
            <scbssfbhxlh>是</scbssfbhxlh>
            <scbssfbhscrq>是</scbssfbhscrq>
            <scbssfbhsxrq>否</scbssfbhsxrq>
            <tscchcztj></tscchcztj>
            <tsccsm></tsccsm>
            <deviceRecordKey>0693145010340620240518045505448</deviceRecordKey>
            <versionNumber>1</versionNumber>
            <versionTime>2024-05-20</versionTime>
            <versionStauts>新增</versionStauts>
            <correctionNumber>0</correctionNumber>
            <correctionRemark></correctionRemark>
            <correctionTime></correctionTime>
            <contactList>
                <contact>
                    <qylxrcz></qylxrcz>
                    <qylxryx>[email protected]</qylxryx>
                    <qylxrdh>0769-85160532</qylxrdh>
                </contact>
            </contactList>
        </device>
    </devices>
</udid>
C# 類型示例:
    //為從XML反序列化來而做準備
    public class udid
    {
        public header header { get; set; } = new();
        [XmlArrayItem("device")]//序列化反序列化時,當DeviceInfoDto對應的xml中元素的名字不是DeviceInfoDto而是device時,用該特性指定類型DeviceInfoDto對應的在xml中的元素的名字device。如果不這麼做,則需要變能,改以下代碼中List<DeviceInfoDto>為List<device>其中device為一個繼承自DeviceInfoDto類型的子類
        public List<DeviceInfoDto> devices { get; set; } = new();
    }
    public class header
    {
        [XmlAttribute("frequency")]
        public string Frequency { get; set; } = string.Empty;
        [XmlAttribute("id")]
        public string Id { get; set; } = string.Empty;
        [XmlAttribute("type")]
        public string Type { get; set; } = string.Empty;
        public int downloadFilePart { get; set; }
        public int downloadFileTotalParts { get; set; }
        public int numberRkeyecordXML { get; set; }
        public int numberRecordsDatabase { get; set; }

        #region 當直接使用一個類型為Datetime屬性名為creationDate來在反序列化xml文件中的日期時間類型的接收者時,反序列化會報錯:【字元串“2020-07-31 09:29:16”不是有效的AllXsd值】。於是採入引入一個中間屬性stringCreationDate(類型為string)和存儲其值的欄位_creationDate(類型為DateTime)的方式,運行過程1.當反序列化時從xml文件讀取元素名為creationDate的元素值並通過stringCreationDate的set訪問器將其值在轉值為DateTime類型後存放於欄位_creationDate中 2.當C#代碼中其他地方要訪問這個值時,就從creationDate屬性的get訪問器傳遞出_creationDate欄位的值。缺點:需引入不必要的屬性和欄位,而且屬性名還必須是public的,這會讓外部訪問者對這個中間屬性感到疑惑。
        private DateTime _creationDate;
        [XmlElement(ElementName = "creationDate")]
        public string stringCreationDate { get => _creationDate.ToString("yyyy-MM-dd HH:mm:ss"); set => _creationDate = Convert.ToDateTime(value); }
        [XmlIgnore]
        public DateTime creationDate { get => _creationDate; }
        #endregion
    }


    public class DeviceInfoDto
    {

        [XmlElement("cpmctymc")]//用來在做xml反序列化時,指定本屬性對應到xml文件中的標簽的名字。(註意還有一個是XmlAttribute它是指對應到xml標簽的屬性名字)
        public string CPMCTYMC { get; set; }

        [XmlElement("spmc")]
        public string SPMC { get; set; }

        [XmlElement("ggxh")]
        public string GGXH { get; set; }

        [XmlElement("cpms")]
        public string CPMS { get; set; }

        [XmlElement("tyshxydm")]
        public string TYSHXYDM { get; set; }

        [XmlElement("flbm")]
        public string CategoryCode { get; set; }

        [XmlElement("deviceRecordKey")]
        public string deviceRecordKey { get; set; }

        [XmlElement("versionTime")]
        public DateTime versionTime { get; set; }

        [XmlElement("zxxsdycpbs")]
        public string DI { get; set; }

        [XmlElement("cpbsbmtxmc")]
        public string DeviceCodeType { get; set; }

        [XmlElement("ylqxzcrbarmc")]
        public string Manufacturer { get; set; }

        [XmlElement("ylqxzcrbarywmc")]
        public string EnManufacturer { get; set; }

        [XmlElement("zczbhhzbapzbh")]
        public string RegistrationCertificateNo { get; set; }

        [XmlElement("versionStauts")]
        public string versionStauts { get; set; }
    }

註意其中幾個關鍵點

1. 讀取xml文件時,以獨占方式,這樣可以避免文件被別的程式打開時讀取報錯的問題。

using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {}

2. 在序列化反序列化時,當類型DeviceInfoDto對應的xml中元素的名字不是DeviceInfoDto而是device時,有兩種解決方法:

方法一:
用該特性[XmlArrayItem("device")]指定類型DeviceInfoDto對應的在xml中的元素的名字device。

        [XmlArrayItem("device")]
        public List<DeviceInfoDto> devices { get; set; } = new();

方法二:
需要變通:改以下代碼中List<DeviceInfoDto>List<device>其中device為一個繼承自DeviceInfoDto類型的子類
public List<device> devices { get; set; } = new();

public class device:DeviceInfoDto
{
}

3. 反序列化時對應C#類型DateTime時的報錯處理

當直接使用一個類型為Datetime屬性名為creationDate來在反序列化xml文件中的日期時間類型的接收者時,反序列化會報錯:【字元串“2020-07-31 09:29:16”不是有效的AllXsd值】。於是採入引入一個中間屬性stringCreationDate(類型為string)和存儲其值的欄位_creationDate(類型為DateTime)的方式,運行過程1.當反序列化時從xml文件讀取元素名為creationDate的元素值並通過stringCreationDate的set訪問器將其值在轉值為DateTime類型後存放於欄位_creationDate中 2.當C#代碼中其他地方要訪問這個值時,就從creationDate屬性的get訪問器傳遞出_creationDate欄位的值。缺點:需引入不必要的屬性和欄位,而且屬性名還必須是public的,這會讓外部訪問者對這個中間屬性感到疑惑。

        private DateTime _creationDate;
        [XmlElement(ElementName = "creationDate")]
        public string stringCreationDate { get => _creationDate.ToString("yyyy-MM-dd HH:mm:ss"); set => _creationDate = Convert.ToDateTime(value); }
        [XmlIgnore]
        public DateTime creationDate { get => _creationDate; }

4. 序列化反序列化時,XmlSerializer可識別的常用的C#特性標簽 Attribute

a. [XmlRoot("udid")]
用於C#類名上,用於指明根類型對應的xml中的元素名
b. [XmlElement("creationDate")]
用於C#屬性或欄位上,用於指明屬性對應的xml元素名或者叫標簽名為 creationDate
c. [XmlAttribute("frequency")]
用於C#屬性或欄位上,用於指明屬性或欄位對應的XML元素的屬性名為 frequency
d. [XmlIgnore]
用於C#屬性或欄位上,用來標記該欄位在序列化反序列化XML文檔時是要忽略的C#屬性或欄位
e. [XmlArrayItem("device")]
用於C# List<T>集合類型的屬性或欄位上,用來標記集合中的元素類型T在XML文檔中對應的元素名稱

更多參考:

https://www.cnblogs.com/guogangj/p/7489218.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文介紹了註意力機制的基本原理,並使用 Python 和 TensorFlow/Keras 實現了一個簡單的註意力機制模型應用於文本分類任務。 ...
  • bolo-solo —— Bolo菠蘿博客,一個基於 Java 實現的博客系統,簡單易部署,具有精緻的主題,專為程式員設計。 ...
  • Stream API 是 Java 8 中最為重要的更新之一,是處理集合的關鍵抽象概念,也是每個 Java 後端開發人員都必須無條件掌握的內容。 在之前的開發中,遇到了這樣的需求:記錄某個更新操作之前的數據作為日誌內容,之後可以供管理員在頁面上查看該日誌。 ...
  • 在軟體開發過程中,集成測試是至關重要的一環。它確保不同組件之間的協作正常,並驗證系統在整體上的功能和性能。然而,傳統的集成測試往往需要依賴於外部資源,如資料庫、消息隊列等,這給測試環境的搭建和維護帶來了一定的挑戰。 為瞭解決這個問題,我們可以使用 TestContainers 這個強大的開源工具。T ...
  • 前言:說到爬蟲,基本上清一色的都知道用Python,但是對於一些沒玩過或者不想玩Python的來說,卻比較頭大一點。所以以下我站在C# 的角度,來寫一個簡單的Demo,用來演示C# 實現的簡單小爬蟲。大家感興趣可以自己拓展出更加豐富的爬蟲功能。 前提:引用包HtmlAgilityPack 先來個爬取 ...
  • 自動篩選器是 Excel 中的一個基本但極其有用的功能,它可以讓你根據特定的條件來自動隱藏和顯示你的數據。當有大量的數據需要處理時,這個功能可以幫你快速找到你需要的信息,從未更加有效地分析和處理相關數據。 下麵將介紹如何使用免費.NET Excel庫在Excel中添加、應用和刪除自動篩選器。包含以下 ...
  • 最近YOLO家族又添新成員:YOLOv10,YOLOv10 提出了一種一致的雙任務方法,用於無nms訓練的YOLOs,它同時帶來了具有競爭力的性能和較低的推理延遲。此外,還介紹了整體效率-精度驅動的模型設計策略,從效率和精度兩個角度對YOLOs的各個組成部分進行了全面優化,大大降低了計算開銷,增強了... ...
  • 不管是在控制台程式還是asp.net core程式中,我們經常會有用到一個需要長時間運行的後臺任務的需求。通常最直覺的方式是使用Thread實例來新建一個線程,但是這樣需要自行管理線程的啟動和停止。 在.net core中提供了一個繼承自IHostedService的基類BackgroudServi ...
一周排行
    -Advertisement-
    Play Games
  • PasteSpider是什麼? 一款使用.net編寫的開源的Linux容器部署助手,支持一鍵發佈,平滑升級,自動伸縮, Key-Value配置,項目網關,環境隔離,運行報表,差量升級,私有倉庫,集群部署,版本管理等! 30分鐘上手,讓開發也可以很容易的學會在linux上部署你得項目! [從需求角度介 ...
  • SQLSugar是什麼 **1. 輕量級ORM框架,專為.NET CORE開發人員設計,它提供了簡單、高效的方式來處理資料庫操作,使開發人員能夠更輕鬆地與資料庫進行交互 2. 簡化資料庫操作和數據訪問,允許開發人員在C#代碼中直接操作資料庫,而不需要編寫複雜的SQL語句 3. 支持多種資料庫,包括但 ...
  • 在C#中,經常會有一些耗時較長的CPU密集型運算,因為如果直接在UI線程執行這樣的運算就會出現UI不響應的問題。解決這類問題的主要途徑是使用多線程,啟動一個後臺線程,把運算操作放在這個後臺線程中完成。但是原生介面的線程操作有一些難度,如果要更進一步的去完成線程間的通訊就會難上加難。 因此,.NET類 ...
  • 一:背景 1. 講故事 前些天有位朋友在微信上丟了一個崩潰的dump給我,讓我幫忙看下為什麼出現了崩潰,在 Windows 的事件查看器上顯示的是經典的 訪問違例 ,即 c0000005 錯誤碼,不管怎麼說有dump就可以上windbg開幹了。 二:WinDbg 分析 1. 程式為誰崩潰了 在 Wi ...
  • CSharpe中的IO+NPOI+序列化 文件文件夾操作 學習一下常見的文件、文件夾的操作。 什麼是IO流? I:就是input O:就是output,故稱:輸入輸出流 將數據讀入記憶體或者記憶體輸出的過程。 常見的IO流操作,一般說的是[記憶體]與[磁碟]之間的輸入輸出。 作用 持久化數據,保證數據不再 ...
  • C#.NET與JAVA互通之MD5哈希V2024 配套視頻: 要點: 1.計算MD5時,SDK自帶的計算哈希(ComputeHash)方法,輸入輸出參數都是byte數組。就涉及到字元串轉byte數組轉換時,編碼選擇的問題。 2.輸入參數,字元串轉byte數組時,編碼雙方要統一,一般為:UTF-8。 ...
  • CodeWF.EventBus,一款靈活的事件匯流排庫,實現模塊間解耦通信。支持多種.NET項目類型,如WPF、WinForms、ASP.NET Core等。採用簡潔設計,輕鬆實現事件的發佈與訂閱。通過有序的消息處理,確保事件得到妥善處理。簡化您的代碼,提升系統可維護性。 ...
  • 一、基本的.NET框架概念 .NET框架是一個由微軟開發的軟體開發平臺,它提供了一個運行時環境(CLR - Common Language Runtime)和一套豐富的類庫(FCL - Framework Class Library)。CLR負責管理代碼的執行,而FCL則提供了大量預先編寫好的代碼, ...
  • 本章將和大家分享在ASP.NET Core中如何使用高級客戶端NEST來操作我們的Elasticsearch。 NEST是一個高級別的Elasticsearch .NET客戶端,它仍然非常接近原始Elasticsearch API的映射。所有的請求和響應都是通過類型來暴露的,這使得它非常適合快速上手 ...
  • 參考delphi的代碼更改為C# Delphi 檢測密碼強度 規則(仿 google) 仿 google 評分規則 一、密碼長度: 5 分: 小於等於 4 個字元 10 分: 5 到 7 字元 25 分: 大於等於 8 個字元 二、字母: 0 分: 沒有字母 10 分: 全都是小(大)寫字母 20 ...