Preserve element contents for spaces only when XML deserialization using XmlSerializer

I have an InputConfig class that 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); 

He works like a champion! Lightweight material, except that when deserializing I have to keep spaces in the function element. The generated XML file demonstrates that spaces remained during serialization, but it is lost during deserialization.

 <IncludeExcludeRules> <IncludeExcludeRule> <Idx>17</Idx> <Name>LIEN</Name> <Operation>E =</Operation> <Function> </Function> </IncludeExcludeRule> </IncludeExcludeRules> 

The MSDN documentation for XmlAttributeAttribute seems to refer to this same problem under the heading Notes , but I don’t understand how to use it. It provides this example:

 // Set this to 'default' or 'preserve'. [XmlAttribute("space", Namespace = "http://www.w3.org/XML/1998/namespace")] public string Space 

A? Ask what to do with "default" or "save"? I'm sure I'm close, but that just doesn't make sense. I need to think that only one line of XmlAttribute should be inserted into the class before the member to preserve the space when deserializing.

There are many examples of similar issues here and elsewhere, but they all seem to be related to using XmlReader and XmlDocument, or to tricking with individual nodes, etc. I would like to avoid this depth.

+6
source share
4 answers

To preserve all spaces during XML deserialization, just create and use the 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) retains only significant spaces marked with the xml:space="preserve" attribute.

+5
source

Hidden documentation means that you need to specify an additional field with [XmlAttribute("space", Namespace = "http://www.w3.org/XML/1998/namespace")] , whose value is equal to default or preserve . XmlAttribute controls the name of the generated attribute for a field or property. The attribute value is the value of the field.

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:

 <?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" /> 
+3
source

I believe that the part you are missing is adding xml:space="preserve" to the field, for example:

 <Function xml:space="preserve"> </Function> 

For more information, see XML Specification.

With annotation in the class definition, according to the MSDN blog, it should be:

 [XmlAttribute("space=preserve")] 

but I remember that it

 [XmlAttribute("xml:space=preserve")] 
+1
source

Michael Liu answered above, worked for me, but with one warning. I would comment on his answer, but my "reputation" is not adequate enough.

I found that using XmlReader did not completely fix the problem, and the reason for this is because the .net property in question has an attribute:

 XmlText(DataType="normalizedString") 

To fix this, I found that adding an additional attribute:

 [XmlAttribute("xml:space=preserve")] 

Obviously, if you do not have control over the .net class, you will have a problem.

0
source

All Articles