I have a class InputConfig
which contains a List<IncludeExcludeRule>
:
public class InputConfig
{
// The rest of the class omitted
private List<IncludeExcludeRule> includeExcludeRules;
public List<IncludeExcludeRule> IncludeExcludeRules
{
get { return includeExcludeRules; }
set { includeExcludeRules = value; }
}
}
public class IncludeExcludeRule
{
// Other members omitted
private int idx;
private string function;
public int Idx
{
get { return idx; }
set { idx = value; }
}
public string Function
{
get { return function; }
set { function = value; }
}
}
Using ...
FileStream fs = new FileStream(path, FileMode.Create);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(InputConfig));
xmlSerializer.Serialize(fs, this);
fs.Close();
... and ...
StreamReader sr = new StreamReader(path);
XmlSerializer reader = new XmlSerializer(typeof(InputConfig));
InputConfig inputConfig = (InputConfig)reader.Deserialize(sr);
It works like a champ! Easy stuff, except that I need to preserve whitespace in the member function
when deserializing. The generated XML file demonstrates that the whitespace was preserved when serializing, but it is lost on deserializing.
<IncludeExcludeRules>
<IncludeExcludeRule>
<Idx>17</Idx>
<Name>LIEN</Name>
<Operation>E =</Operation>
<Function> </Function>
</IncludeExcludeRule>
</IncludeExcludeRules>
The MSDN documentation for XmlAttributeAttribute seems to address this very issue under the header Remarks, yet I don't understand how to put it to use. It provides this example:
// Set this to 'default' or 'preserve'.
[XmlAttribute("space",
Namespace = "http://www.w3.org/XML/1998/namespace")]
public string Space
Huh? Set what to 'default' or 'preserve'? I'm sure I'm close, but this just isn't making sense. I have to think there's just a single line XmlAttribute to insert in the class before the member to preserve whitespace on deserialize.
There are many instances of similar questions here and elsewhere, but they all seem to involve the use of XmlReader and XmlDocument, or mucking about with individual nodes and such. I'd like to avoid that depth.
Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.
public XMLSerializer(java.io.Writer writer, OutputFormat format) Constructs a new serializer that writes to the specified writer using the specified output format. If format is null, will use a default output format.
Serialization is the process of converting an object into a form that can be readily transported. For example, you can serialize an object and transport it over the Internet using HTTP between a client and a server. On the other end, deserialization reconstructs the object from the stream.
XmlSerializer enables you to control how objects are encoded into XML. The XmlSerializer enables you to control how objects are encoded into XML, it has a number of constructors.
To preserve all whitespace during XML deserialization, simply create and use an XmlReader
:
StreamReader sr = new StreamReader(path);
XmlReader xr = XmlReader.Create(sr);
XmlSerializer reader = new XmlSerializer(typeof(InputConfig));
InputConfig inputConfig = (InputConfig)reader.Deserialize(xr);
Unlike XmlSerializer.Deserialize(XmlReader)
, XmlSerializer.Deserialize(TextReader)
preserves only significant whitespace marked by the xml:space="preserve"
attribute.
The cryptic documentation means that you need to specify an additional field with the [XmlAttribute("space", Namespace = "http://www.w3.org/XML/1998/namespace")]
whose value is default
or preserve
. XmlAttribute controls the name of the generated attribute for a field or property. The attribute's value is the field's value.
For example, this class:
public class Group
{
[XmlAttribute (Namespace = "http://www.cpandl.com")]
public string GroupName;
[XmlAttribute(DataType = "base64Binary")]
public Byte [] GroupNumber;
[XmlAttribute(DataType = "date", AttributeName = "CreationDate")]
public DateTime Today;
[XmlAttribute("space", Namespace = "http://www.w3.org/XML/1998/namespace")]
public string Space ="preserve";
}
Will be serialized to:
<?xml version="1.0" encoding="utf-16"?>
<Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
d1p1:GroupName=".NET"
GroupNumber="ZDI="
CreationDate="2001-01-10"
xml:space="preserve"
xmlns:d1p1="http://www.cpandl.com" />
I believe the part you are missing is to add the xml:space="preserve"
to the field, e.g.:
<Function xml:space="preserve"> </Function>
For more details, here is the relevant section in the XML Specification
With annotation in the class definition, according to the MSDN blog it should be:
[XmlAttribute("space=preserve")]
but I remember it being
[XmlAttribute("xml:space=preserve")]
Michael Liu's answer above worked for me, but with one caveat. I would have commented on his answer, but my "reputation" is not adequate enough.
I found that using XmlReader did not fully fix the issue, and the reason for this is that the .net property in question had the attribute:
XmlText(DataType="normalizedString")
To rectify this I found that adding the additional attribute worked:
[XmlAttribute("xml:space=preserve")]
Obviously, if you have no control over the .net class then you have a problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With