【发布时间】:2015-04-22 11:13:16
【问题描述】:
我有一个可序列化为 XML 的类“产品”。我使用标准 System.Xml.Serialization.XmlSerializer 进行序列化,并使用 XmlWriter 'writer' 对象将序列化结果写入 StreamWriter 对象。序列化器对象现在一次性序列化整个类:
XmlSerializer serializer = new XmlSerializer(typeof(products));
serializer.Serialize(writer, products);
该类有一个名为“规范”的 Dictionary
- 颜色:蓝色
- 长度:110mm
- 宽度:55mm
我希望能够将该属性序列化为:
...
<specifications>
<color>blue</color>
<length>110mm</length>
<width>55mm</width>
</specifications>
...
我知道这是糟糕的 XML 设计,但它必须符合第 3 方规范。
是否有我可以使用的标准属性?如果没有,我怎么能像那样序列化字典?
如果您需要更多代码 sn-ps,请告诉我。
编辑:
由于需求的一些变化,我放弃了 Dictionary
public class Specification
{
public string Name;
public string Value;
public bool IsOther;
public Specification() : this(null, null, false) { }
public Specification(string name, string value) : this(name, value, false) { }
public Specification(string name, string value, bool isOther)
{
Name = name;
Value = value;
IsOther = isOther;
}
}
为了避免通过在产品类中使用“规范”列表来重复元素“规范”,我使用了实现 IXmlSerializable 接口的复数类“规范”:
public class Specifications: IXmlSerializable
{
public List<Specification> Specs = new List<Specification>();
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
//I don't need deserialization, but it would be simple enough now.
throw new System.NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
//write all "standarad", named specs
//this writes the <color>blue</color>-like elements
Specs.Where(s => !s.IsOther).ToList().ForEach(s => writer.WriteElementString(s.Name, s.Value));
//write other specs
//this writes <other_specs>{name|value[;]}*</other_specs>
string otherSpecs = string.Join(";", Specs.Where(s => s.IsOther).Select(s => string.Concat(s.Name, "|", s.Value)));
if (otherSpecs.Length > 0) writer.WriteElementString("other_specs", otherSpecs);
}
}
“规范”类应用为:
public class Product
{
public Product()
{
Specifications = new Specifications();
}
[XmlElement("specs")]
public Specifications Specifications;
//this "feature" will not include <specs/> when there are none
[XmlIgnore]
public bool SpecificationsSpecified { get { return Specifications.Specs.Any(); } }
//...
}
感谢您提供 IXmlSerializable 和 XmlWriter 的示例。我不知道 XmlWriter 的界面和用法 - 它对我来说是一个宝贵的灵感!
*这是我的第一个 SO 问题。关闭它的最合适方法是什么?我没有提供这个作为我自己的答案,因为它不是我最初的问题(关于字典)的真正答案。
【问题讨论】:
-
我认为this sample 可以帮助您:检查
WriteXml方法并根据您的需要进行相应更改... -
你可以看看这里,因为字典本身很遗憾不能序列化:stackoverflow.com/questions/12856456/…
-
你提前知道会出现哪些键,还是需要对出现的任何键进行序列化?
-
这两个例子看起来很有希望;明天我会好好看看。 Dbc,我事先不知道哪些键。
-
建议编辑您的问题以添加您事先不知道密钥。
标签: c# xml serialization dictionary