繁体   English   中英

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

[英]Deserialize Xml with empty elements in C#

尝试将某些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;}   
 }

我可以通过类来设置调整解析吗?
要么
有没有一种简单的方法可以应用xsl来删除这些元素?
要么
我应该使用regEx删除空元素进行去串化吗?
要么
一个更好的方法?

清除这些节点的最统一方法似乎是向反序列化器添加一个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); } 
  static string RemoveText(Match m) { return "";}

如果您无法控制入站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; }
  }
}

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

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

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

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

<foo xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<propOne>1</propOne>
<propTwo xsi:nil='true'/>
</foo>

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

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

为简单起见,为什么不使用XmlDocument和XPath明确解析xml? 使用XPath明确访问每个xml节点,例如

XmlNode node = xml.SelectSingleNode ("foo/PropOne");
if (node != null)
{
     propOneValue = node.innerText;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM