Deserialize Xml with empty elements in C#

后端 未结 4 771
醉梦人生
醉梦人生 2020-12-01 21:16

Trying to deserialize some xml snippits from a vendor into objects. The problem is that I\'m getting an invalid format on every empy element tag. I can deserialize the obj

相关标签:
4条回答
  • 2020-12-01 21:31

    The most uniform way to clean out these nodes appears to be to add a RegEx filter to the deserializer.

        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 "";}
    
    0 讨论(0)
  • 2020-12-01 21:31

    See this article: Can XmlSerializer deserialize into a Nullable?

    In a nutshell your Xml should look like this if you want to use Nullable types:

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

    The two changes are adding the namespace, and explicitly setting xsi:nil to true on the null element.

    If you don't have control over your Xml there is a more advanced technique described here: Using XmlSerializer to deserialize into a Nullable

    0 讨论(0)
  • 2020-12-01 21:38

    For simplicity, why don't you parse the xml explictly using XmlDocument and XPath? Use XPath to explictly access each xml node e.g.

    XmlNode node = xml.SelectSingleNode ("foo/PropOne");
    if (node != null)
    {
         propOneValue = node.innerText;
    }
    
    0 讨论(0)
  • 2020-12-01 21:50

    Another option if you've not got control over the inbound XML is to work around this by having the deserializer pretend that the variable is a string:

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

    The Deserialiser is happy to parse a string element when it's empty, so you make use of that.

    It's not particularly nice, but it'll do if you've only got one or 2 tags to cover

    0 讨论(0)
提交回复
热议问题