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转化成其对应的实体。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值