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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章