XML——c# 實體轉xml最佳實踐(自定義轉化方式)

定義一個接口,包含兩個方法:實體轉xml 和 xml轉實體。包含一個屬性根節點標籤名稱

  /// <summary>
    /// 定義元屬性實體類與Xml之間的轉換接口
    /// </summary>
    /// <typeparam name="T">元屬性實體類</typeparam>
    public interface IEntitySerialization<T>
    {
        /// <summary>
        /// 將實體類<c>T</c>使用<see cref="XmlWriter"/>轉爲XML 數據寫到流、文件、文本
        /// 讀取器或字符串。
        /// </summary>
        /// <param name="writer"><see cref="XmlWriter"/>實例</param>
        void WriteXml(XmlWriter writer);

        /// <summary>
        /// 將<see cref="XmlNode"/>節點的信息轉爲實體類<c>T</c>
        /// </summary>
        /// <param name="node"><see cref="XmlNode"/>實例,該實例包含了<c>T</c>
        /// 實體類所需要的信息</param>
        /// <returns>實體類<c>T</c></returns>
        T GetObject(XmlNode node);

        /// <summary>
        /// 根節點元素標籤名稱
        /// </summary>
        string RootElementName { get; }
    }

定義xml對應的實體,實體都繼承上面的接口

並實現具體實體對應的xml和實體之間的轉化方式


 public class Hape : IEntitySerialization<Hape >
    {
        /// <summary>
        /// 名稱
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 空間座標 WKT格式
        /// </summary>
        public string Geometry { get; set; }

        /// <summary>
        /// 實體轉xml
        /// </summary>
        /// <param name="writer"></param>
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement(this.RootElementName);
            XmlHelper.WriteOptionalAttribute(writer, "name", Name);
            XmlReader reader = XmlReader.Create(new StringReader(DbGeography.FromText(Geometry).AsGml()));
            var gml = Deserialize(reader);
            Serialize(writer, gml);
            writer.WriteEndElement();
        }

        /// <summary>
        /// xml轉實體
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public Hape GetObject(XmlNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (node.Name != this.RootElementName)
            {
                throw new ArgumentException("The element name of node is not " + RootElementName);
            }
            var name = XmlHelper.GetOptionalAttributeValue(node, "name");
            var gml = node.InnerXml.Replace("gml:", "").Replace(":gml", "");
            var geometry = DbGeography.FromGml(gml).AsText();
            return new Shape { Name = name, Geometry = geometry };
        }
        /// <summary>
        /// 根節點標籤名稱
        /// </summary>
        public string RootElementName => "Hape";
    }

一個節點可以包含多個節點的集合

    /// <summary>
    /// 集合
    /// </summary>
    public class HapeCollection : List<Hape>, IEntitySerialization<HapeCollection>
    {
        /// <summary>
        /// 實體轉xml
        /// </summary>
        /// <param name="writer"></param>
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement(this.RootElementName);
            XmlHelper.WriteEntityCollection(writer, this);
            writer.WriteEndElement();
        }

        /// <summary>
        /// xml轉實體
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public HapeCollection GetObject(XmlNode node)
        {
            var result = new HapeCollection();
            var shapeList = XmlHelper.GetEntityCollection<Shape>(node, new hape().RootElementName);
            result.AddRange(shapeList);
            return result;
        }
        /// <summary>
        /// 根節點標籤名稱
        /// </summary>
        public string RootElementName => "Hapes";
    }


以上就定義了實體,以及針對該實體的自定義xml轉化。

當每個實體都實現了xml和實體之間的轉化,就很容易將這些實體組合成一個複雜的實體,並且轉化方法可以很簡單。

下面進行測試查看


給hapeCollection 賦值

            var hape = new Hape() { Name = "口", Geometry = "POINT(4 6)" };
            var hape2 = new Hape() { Name = "地", Geometry = "LINESTRING(47 -122.36 47 -122.343)" };
            var hape3 = new Hape()
            {
                Name = "造",
                Geometry = "POLYGON ((36 108 391 10 36 108 36 108 361 108))"
            };
            Hapes.Add(hape3);
            Hapes.Add(hape2);
            Hapes.Add(hape);
調用該實體的方法 ,轉化成xml

 public void TestHapeCollection()
        {
            var result = "";
            using (MemoryStream ms = new MemoryStream())
            {
                using (XmlWriter writer = XmlHelper.GetXmlWriter(ms))
                {
                    Shapes.WriteXml(writer);
                }
                result = Encoding.UTF8.GetString(ms.ToArray());
                var obj = GetObject<HapeCollection>(result);
            }
        }

最後得到的xml結果爲

<Hapes>
  <Hape name="造">
    <gml:Polygon>
      <gml:exterior>
        <gml:LinearRing>
          <gml:posList>36 108 391 10 36 108 36 108 361 108</gml:posList>
        </gml:LinearRing>
      </gml:exterior>
    </gml:Polygon>
  </Hape>
  <Hape name="地">
    <gml:LineString">
      <gml:posList>47 -122.36 47 -122.343</gml:posList>
    </gml:LineString>
  </Hape>
  <Hape name="口">
    <gml:Point>
      <gml:pos>6 4</gml:pos>
    </gml:Point>
  </Hape>
</Hapes>

也可以將上面的xml轉化成其對應的實體。



發佈了177 篇原創文章 · 獲贊 88 · 訪問量 83萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章