序列化时,在生成的xml中去掉不必要的标签?

zwaleaf 2009-06-10 12:39:50
比如生成的xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<ReportChart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CategoryGroupings>
<CategoryGrouping>aa</CategoryGrouping>
</CategoryGroupings>
</ReportChart>

说明: <CategoryGroupings>标签下有0-n个子标签<CategoryGrouping>,当子标签数目为0时,则去掉整个<CategoryGroupings>标签.
我的ReportChart类如下,这样的问题是:序列化时,若<CategoryGroupings>子标签个数为0, 在xml中<CategoryGroupings>仍存在.


using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace Com
{
[Serializable]
public class ReportChart
{
private List<String> categoryGroupingList = new List<String>();

[XmlArray("CategoryGroupings")]
[XmlArrayItem("CategoryGrouping")]
public List<String> CategoryGroupingList
{
get { return categoryGroupingList; }
set { categoryGroupingList = value; }
}
}
}



若修改ReportChart中属性如下,虽然可以去掉不必要的<CategoryGroupings>标签(当子标签个数为0时),但反序列化时得到CategoryGroupingList的Count始终为0(不论子标签个数为多少)。不知如何解决?

[XmlIgnore]
public List<String> CategoryGroupingList
{
get { return categoryGroupingList; }
set { categoryGroupingList = value; }
}

[XmlArray("CategoryGroupings")]
[XmlArrayItem("CategoryGrouping")]
public List<String> CategoryGroupingListSerial
{
get
{
if (categoryGroupingList.Count == 0)
{
return null;
}
return categoryGroupingList;
}

set {
categoryGroupingList = value;
}
}



另外附一个用于序列化和反序列化的类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace Com
{
public static class XmlUtil
{
public static object Deserialize(string xml, Type type)
{
XmlSerializer xs = new XmlSerializer(type);
StringReader sr = new StringReader(xml);
object obj = xs.Deserialize(sr);
return obj;
}

public static void SaveXml(string filePath, object obj)
{
SaveXml(filePath, obj, null);
}

public static void SaveXml(string filePath, object obj, XmlSerializerNamespaces nameSpace)
{
if (obj == null)
{
return;
}
Type type = obj.GetType();
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(filePath, false, Encoding.UTF8))
{
try
{
XmlSerializer xs = new XmlSerializer(type);
if (nameSpace != null)
{
xs.Serialize(writer, obj, nameSpace);
}
else
{
xs.Serialize(writer, obj);
}
}
catch (Exception ex)
{
Console.WriteLine("exception :" + ex + " is null: " + (ex == null));
}
writer.Close();
}
}
public static object LoadXml(string filePath, System.Type type)
{
if (!System.IO.File.Exists(filePath))
return null;
using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath))
{
XmlSerializer xs = new XmlSerializer(type);
try
{
object obj = xs.Deserialize(reader);
reader.Close();
return obj;
}
catch (Exception e)
{
}
return null;
}
}
}
}

...全文
526 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
bljbljbljblj 2011-04-09
  • 打赏
  • 举报
回复
唉,顾此失彼,习惯了用 A.Items.Add(....)这样调用了。如果 Items.Count=0就返回null的话,会有很多问题的。大家自己斟酌吧
zwaleaf 2009-06-11
  • 打赏
  • 举报
回复
在4楼发的这种做法还是有问题.虽然序列化时可以满足要求.
但是反序列化的时候,当<CategoryGroupings>里面有多个子元素<CategoryGrouping>时,取到的categoryGroupingList的Count始终为0,
用数组代替,得到正确结果,特意更正下,免得误导人.Sigh
正确代码如下:

namespace Com
{
[Serializable]
public class ReportChart
{
private List<String> categoryGroupingList;

[XmlIgnore]
public List<String> CategoryGroupingList
{
get { return categoryGroupingList; }
set { categoryGroupingList = value; }
}

[XmlArray("CategoryGroupings")]
[XmlArrayItem("CategoryGrouping")]
public String[] CategoryGroupingListSerial
{
get
{
if (categoryGroupingList == null || categoryGroupingList.Count == 0)
{
return null;
}
return categoryGroupingList.ToArray();
}
set {
if (value == null)
{
categoryGroupingList = null;
}
else
{
categoryGroupingList = new List<string>();
categoryGroupingList.AddRange(value);
}
}
}
}
}

龙宜坡 2009-06-10
  • 打赏
  • 举报
回复
不太好控制,期待高人!!

另借贵地提个问题,怎么把注释一同序列化到XML文件中?谢谢!
lovvver 2009-06-10
  • 打赏
  • 举报
回复
楼主这样解决很聪明,呵呵
zwaleaf 2009-06-10
  • 打赏
  • 举报
回复
结贴!
还是很谢谢2 楼 lovvver 的回复。
我自己解决了。
分就给你啦 :)
代码如下:


namespace Com
{
[Serializable]
public class ReportChart
{
//此处不能初始化:categoryGroupingList = new List<String>();
private List<String> categoryGroupingList;

[XmlIgnore]
public List<String> CategoryGroupingList
{
get { return categoryGroupingList; }
set { categoryGroupingList = value; }
}

[XmlArray("CategoryGroupings")]
[XmlArrayItem("CategoryGrouping")]
public List<String> CategoryGroupingListSerial
{
//Load(Deserialize): categoryGroupingList == null
//Save(Serialize): categoryGroupingList == null || categoryGroupingList.Count == 0
get
{
if (categoryGroupingList == null || categoryGroupingList.Count == 0)
{
return null;
}
return categoryGroupingList;
}
//set {categoryGroupingList = value;}
}

}
}

zwaleaf 2009-06-10
  • 打赏
  • 举报
回复
在外面给CategoryGroupingList赋值虽然有些效果,但还没有满足需求。
就是这样的话,ReportChart如果有多个这样的List, 每次序列化时,还得在外面判断List.Count是否为0,如果是,则设置List为null,这就麻烦了。
如果ReportChart里面引用到其他类,如此嵌套,里层的类里面也含有List,同样需要满足需求,岂不是在序列化时,还得逐渐获取里层的类,然后判断List.Count是否为0,如果是,则设置List为null....

有没有什么好办法呢?

[Quote=引用 2 楼 lovvver 的回复:]
如果为空数组:
ReportChart chart = new ReportChart();
chart.CategoryGroupingList = new List <string>();

[/Quote]
lovvver 2009-06-10
  • 打赏
  • 举报
回复
如果为空数组:
ReportChart chart = new ReportChart();
chart.CategoryGroupingList = new List<string>();
->
<?xml version="1.0" encoding="utf-8"?>
<ReportChart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CategoryGroupings />
</ReportChart>

如果为null:
ReportChart chart = new ReportChart();
chart.CategoryGroupingList = null;
->
<?xml version="1.0" encoding="utf-8"?>
<ReportChart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧