使用XmlSerializer反序列化XML时,保留仅限空白的元素内容

时间:2015-10-15 15:41:27

标签: c# .net xml whitespace xmlserializer

我的课程InputConfig包含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; }
    }
}

使用......

FileStream fs = new FileStream(path, FileMode.Create);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(InputConfig));
xmlSerializer.Serialize(fs, this);
fs.Close();

......和......

StreamReader sr = new StreamReader(path);
XmlSerializer reader = new XmlSerializer(typeof(InputConfig));
InputConfig inputConfig = (InputConfig)reader.Deserialize(sr);

它像冠军一样!简单的东西,除了我需要在反序列化时保留成员function中的空格。生成的XML文件表明序列化时保留了空格,但在反序列化时丢失了。

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

MSDN documentation for XmlAttributeAttribute似乎在标题备注下解决了这个问题,但我不明白如何使用它。它提供了这个例子:

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

咦?设置“默认”或“保留”的内容?我确定我很接近,但这只是没有意义。我必须认为在成员之前只有一行XmlAttribute插入到成员中以在反序列化时保留空格。

在这里和其他地方有许多类似问题的实例,但它们似乎都涉及使用XmlReader和XmlDocument,或者涉及单个节点等。我想避免这种深度。

4 个答案:

答案 0 :(得分:5)

要在XML反序列化期间保留所有空格,只需创建并使用XmlReader

StreamReader sr = new StreamReader(path);
XmlReader xr = XmlReader.Create(sr);
XmlSerializer reader = new XmlSerializer(typeof(InputConfig));
InputConfig inputConfig = (InputConfig)reader.Deserialize(xr);

XmlSerializer.Deserialize(XmlReader)不同,XmlSerializer.Deserialize(TextReader)仅保留由xml:space="preserve"属性标记的重要空白。

答案 1 :(得分:4)

隐秘文档意味着您需要指定其[XmlAttribute("space", Namespace = "http://www.w3.org/XML/1998/namespace")]值为defaultpreserve的其他字段。 XmlAttribute控制字段或属性的生成属性的名称。属性的值是字段的值。

例如,这个类:

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";
}

将序列化为:

<?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" />

答案 2 :(得分:1)

我相信您缺少的部分是将xml:space="preserve"添加到字段中,例如:

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

有关详细信息,请参阅XML Specification

中的相关部分

在类定义中使用注释,根据MSDN博客,它应该是:

[XmlAttribute("space=preserve")]

但我记得它是

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

答案 3 :(得分:1)

迈克尔刘的上述答案对我有用,但有一点需要注意。我会评论他的答案,但我的声誉和#34;还不够。

我发现使用XmlReader并没有完全解决问题,原因是有问题的.net属性具有以下属性:

XmlText(DataType="normalizedString")

为了纠正这个问题,我发现添加附加属性有效:

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

显然,如果您无法控制.net类,那么您就会遇到问题。