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
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...