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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...