[英]Set default value for attributes which are null while deserializing XML
我有一個要反序列化的xml文件。 我正在實現用於序列化和反序列化的IXmlSerializable接口。 我看不到序列化有任何問題。 但是通過反序列化,我幾乎沒有問題。 1)。 我正在使用xml閱讀器的“ ReadToFollowing”來讀取元素。 使用這種方法,我必須按元素順序讀取值。 如果順序不匹配,我將無法讀取restig值。 2)。 根據我的要求,我必須在反序列化xml中提供向后兼容性。 因此,當我加載一些舊版本的xml文件(可能不包含所有元素作為最新版本的xml)時,“ ReadToFollowing”引發異常。
最新版本Xml
<LEFTSECTION>
<DATA />
<FONTNAME>Arial</FONTNAME>
<FONTSTYLE>Regular</FONTSTYLE>
<FONTSIZE>10</FONTSIZE>
<TEXTCOLOR>-16777216</TEXTCOLOR>
<STRIKEOUT>0</STRIKEOUT>
<UNDERLINE>0</UNDERLINE>
<BORDER>0</BORDER>
<IMAGE>0</IMAGE>
<IMAGENAME />
<ALIGNMENT>4</ALIGNMENT>
<SECTIONHEIGHT>0.5454546</SECTIONHEIGHT>
<SECTIONWIDTH>0.33</SECTIONWIDTH>
</LEFTSECTION>
舊版本Xml
<LEFTSECTION>
<DATA>asas#APP_OEM_NAME#</DATA>
<FONTNAME>Arial Unicode MS</FONTNAME>
<FONTSTYLE>Regular</FONTSTYLE>
<FONTSIZE>10</FONTSIZE>
<TEXTCOLOR>-16777216</TEXTCOLOR>
<STRIKEOUT>0</STRIKEOUT>
<UNDERLINE>0</UNDERLINE>
<BORDER>0</BORDER>
<IMAGE>0</IMAGE>
<IMAGENAME>
</IMAGENAME>
</LEFTSECTION>
請幫我。
好的。 我玩過,這是我想出的:
可序列化的類:
[Serializable]
[XmlRoot("LEFTSECTION")]
public class NewClass
{
[XmlElement("DATA")]
[System.ComponentModel.DefaultValueAttribute("")]
public string Data;
[XmlElement("FONTNAME")]
public string FontName;
[XmlElement("FONTSTYLE")]
public string FontStyle;
[XmlElement("FONTSIZE")]
public int FontSize;
[XmlElement("TEXTCOLOR")]
public int TextColor;
[XmlElement("STRIKEOUT")]
public int Strikeout;
[XmlElement("UNDERLINE")]
public int Underline;
[XmlElement("BORDER")]
public int Border;
[XmlElement("IMAGE")]
public int Image;
[XmlElement("IMAGENAME")]
public string ImageName;
[System.ComponentModel.DefaultValue(0)]
[XmlElement("ALIGNMENT")]
public int Alignment;
[XmlElement("SECTIONHEIGHT")]
public double SectionHeight;
[XmlElement("SECTIONWIDTH")]
public double SectionWidth;
}
然后在我的測試程序中編寫代碼:
NewClass test = new NewClass();
XmlSerializer serializer = new XmlSerializer(typeof(NewClass));
FileStream file = new FileStream("input.xml", FileMode.Open);
test = (NewClass) serializer.Deserialize(file);
file.Close();
file = new FileStream("old.xml", FileMode.Open);
test = (NewClass)serializer.Deserialize(file);
file.Close();
input.xml的內容:
<?xml version="1.0" encoding="utf-8" ?>
<LEFTSECTION>
<DATA />
<FONTNAME>Arial</FONTNAME>
<FONTSTYLE>Regular</FONTSTYLE>
<FONTSIZE>10</FONTSIZE>
<TEXTCOLOR>-16777216</TEXTCOLOR>
<STRIKEOUT>0</STRIKEOUT>
<UNDERLINE>0</UNDERLINE>
<BORDER>0</BORDER>
<IMAGE>0</IMAGE>
<IMAGENAME />
<ALIGNMENT>4</ALIGNMENT>
<SECTIONHEIGHT>0.5454546</SECTIONHEIGHT>
<SECTIONWIDTH>0.33</SECTIONWIDTH>
</LEFTSECTION>
old.xml的內容:
<LEFTSECTION>
<DATA>asas#APP_OEM_NAME#</DATA>
<FONTNAME>Arial Unicode MS</FONTNAME>
<FONTSTYLE>Regular</FONTSTYLE>
<FONTSIZE>10</FONTSIZE>
<TEXTCOLOR>-16777216</TEXTCOLOR>
<STRIKEOUT>0</STRIKEOUT>
<UNDERLINE>0</UNDERLINE>
<BORDER>0</BORDER>
<IMAGE>0</IMAGE>
<IMAGENAME>
</IMAGENAME>
</LEFTSECTION>
這樣可以正確填充我的班級。 注意,在我的類的Data
和Alignment
屬性中,我設置了默認值(如果不存在)。 同樣,它們都從文件中的內容重命名。
我希望這個對你有用。
編輯
啊,我明白了,您對類的使用IXmlSerializable方法感到困惑。
試試看這不是很漂亮,但它似乎可以工作:
這是我的IXMLSerializable類:
public class XmlSerializableNewClass : IXmlSerializable
{
public string Data;
public string FontName;
public string FontStyle;
public int FontSize;
public int TextColor;
public int Strikeout;
public int Underline;
public int Border;
public int Image;
public string ImageName;
public int Alignment;
public double SectionHeight;
public double SectionWidth;
public string[]elementNames={"DATA", "FONTNAME", "FONTSTYLE","FONTSIZE","TEXTCOLOR","STRIKEOUT", "UNDERLINE", "BORDER", "IMAGE", "IMAGENAME", "ALIGNMENT", "SECTIONHEIGHT", "SECTIONWIDTH"};
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
//set default values
Data=string.Empty;
FontName = string.Empty;
FontStyle = string.Empty;
FontSize = 0;
TextColor = 0;
Strikeout = 0;
Underline = 0;
Border = 0;
Image = 0;
ImageName = string.Empty;
Alignment = 0;
SectionHeight = 0.0;
SectionWidth = 0.0;
reader.MoveToContent();
Boolean isEmptyElement= false;
isEmptyElement = reader.IsEmptyElement;
reader.ReadStartElement();
for (int i=0; i< elementNames.Length; i++)
{
isEmptyElement = reader.IsEmptyElement;
string s = reader.Name;
switch (s)
{
case "DATA":
if (!isEmptyElement)
{
Data = reader.ReadElementString("DATA");
}
else
{
Data = string.Empty;
reader.ReadStartElement();
}
break;
case "FONTNAME":
if (!isEmptyElement)
{
FontName = reader.ReadElementString("FONTNAME");
}
else
{
FontName = string.Empty;
reader.ReadStartElement();
}
break;
case "FONTSTYLE":
if (!isEmptyElement)
{
FontStyle = reader.ReadElementString("FONTSTYLE");
}
else
{
FontStyle = string.Empty;
reader.ReadStartElement();
}
break;
case "FONTSIZE":
if (!isEmptyElement)
{
FontSize = reader.ReadElementContentAsInt();
}
else
{
FontSize = 0;
reader.ReadEndElement();
}
break;
case "TEXTCOLOR":
if (!isEmptyElement)
{
TextColor = reader.ReadElementContentAsInt();
}
else
{
TextColor = 0;
reader.ReadStartElement();
}
break;
case "STRIKEOUT":
if (!isEmptyElement)
{
Strikeout = reader.ReadElementContentAsInt();
}
else
{
Strikeout = 0;
reader.ReadStartElement();
}
break;
case "UNDERLINE":
if (!isEmptyElement)
{
Underline = reader.ReadElementContentAsInt();
}
else
{
Underline = 0;
reader.ReadStartElement();
}
break;
case "BORDER":
if (!isEmptyElement)
{
Border = reader.ReadElementContentAsInt();
}
else
{
Border = 0;
reader.ReadStartElement();
}
break;
case "IMAGE":
if (!isEmptyElement)
{
Image = reader.ReadElementContentAsInt();
}
else
{
Image = 0;
reader.ReadStartElement();
}
break;
case "IMAGENAME":
if (!isEmptyElement)
{
ImageName = reader.ReadElementString("IMAGENAME");
}
else
{
ImageName = string.Empty;
reader.ReadStartElement();
}
break;
case "ALIGNMENT":
if (!isEmptyElement)
{
Alignment = reader.ReadElementContentAsInt();
}
else
{
Alignment = 0;
reader.ReadStartElement();
}
break;
case "SECTIONHEIGHT":
if (!isEmptyElement)
{
SectionHeight = reader.ReadElementContentAsDouble();
}
else
{
SectionHeight = 0;
reader.ReadStartElement();
}
break;
case "SECTIONWIDTH":
if (!isEmptyElement)
{
SectionWidth = reader.ReadElementContentAsDouble();
}
else
{
SectionWidth = 0;
reader.ReadEndElement();
}
break;
}
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
throw new NotImplementedException();
}
#endregion
}
我在處理空元素方面有些落伍。
這是調用代碼,其他所有內容都相同:
XmlSerializableNewClass test2 = new XmlSerializableNewClass();
System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings();
settings.ConformanceLevel = System.Xml.ConformanceLevel.Fragment;
settings.IgnoreWhitespace = true;
settings.IgnoreComments = true;
System.Xml.XmlReader reader = System.Xml.XmlReader.Create("input.xml", settings);
test2.ReadXml(reader);
reader = System.Xml.XmlReader.Create("old.xml", settings);
test2.ReadXml(reader);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.