在C#中使用空元素反序列化Xml

Rya*_*hek 20 c# xml serialization

尝试将某些xml snippit从供应商反序列化为对象.问题是我在每个empy元素标签上获得的格式无效.当所有元素都有值时,我可以反复排序对象没问题.或者省略空元素.

Xml Snippit:

<foo>
<propOne> 1 </ propOne>
<propTwo />
</ foo>

C#类:

[Serialilbe()]     
public class foo
{ 
   public foo(){}
   [XmlElementAttribute(IsNullable = true)]
   public int? propOne {get;set;} 
   [XmlElementAttribute(IsNullable = true)]
   public int? propTwo {get;set;}   
 }
Run Code Online (Sandbox Code Playgroud)

我可以通过类来设置调整解析吗?
或者
有一种简单的方法我可以应用xsl来删除这些元素吗?
或者
我应该使用regEx删除空元素进行预先解密?
还是
更好的方式?

Rya*_*hek 13

清除这些节点的最统一方法似乎是向反序列化器添加一个RegEx过滤器.

    public static T Deserialize<T>(string xml){
        XmlSerializer xs = new XmlSerializer(typeof(T));
        string cleanXml = Regex.Replace(xml, @"<[a-zA-Z].[^(><.)]+/>",
                                        new MatchEvaluator(RemoveText));
        MemoryStream memoryStream = new MemoryStream((new UTF8Encoding()).GetBytes(cleanXml));
        XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
        return (T)xs.Deserialize(memoryStream);
    }
Run Code Online (Sandbox Code Playgroud)
  static string RemoveText(Match m) { return "";}
Run Code Online (Sandbox Code Playgroud)


Rei*_*l-- 10

如果您无法控制入站XML,另一个选择是通过让反序列化程序假装该变量是一个字符串来解决此问题:

[Serializable()]     
public class foo
{ 
  public foo(){}

  [XmlElement("propOne")]
  [EditorBrowsable(EditorBrowsableState.Never)]
  public string propOneString {get;set;}

  [XmlIgnore]
  private int? propOneInternal = null;
  [XmlIgnore]
  private bool propOneSet = false;

  [XmlIgnore]
  public int? propOne
  {
    get
    {
      if (!propOneSet)
      {
        if(!string.IsNullOrEmpty(propOneString)
        {
          propOneInternal = int.Parse(propOneString);
        }
        //else leave as pre-set default: null
        propOneSet = true;
      }
      return propOneInternal;
    }
    set { propOneInternal = value; }
  }
}
Run Code Online (Sandbox Code Playgroud)

Deserialiser很高兴在字符串元素为空时解析它,因此您可以使用它.

这不是特别好,但如果你只有一个或两个标签可以覆盖,那就可以了


And*_*son 9

看到这篇文章:XmlSerializer可以反序列化为Nullable吗?

简而言之,如果你想使用Nullable类型,你的Xml应该是这样的:

<foo xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<propOne>1</propOne>
<propTwo xsi:nil='true'/>
</foo>
Run Code Online (Sandbox Code Playgroud)

这两个更改是添加命名空间,并在null元素上显式设置xsi:nil为true.

如果您无法控制Xml,则可以使用此处描述的更高级技术: 使用XmlSerializer反序列化为Nullable