在C#中使用空元素反序列化Xml
尝试将某些xml snippit从供应商反序列化为对象。 问题是我在每个empy元素标签上获得的格式无效。 当所有元素都有值时,我可以反复排序对象没问题。 或者省略空元素。
Xml Snippit:
1
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来删除空元素吗?
要么
一个更好的方法?
清除这些节点的最统一方法似乎是向反序列化器添加一个RegExfilter。
public static T Deserialize
(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 "";}
看到这篇文章: XmlSerializer可以反序列化为Nullable吗?
简而言之,如果你想使用Nullable类型,你的Xml应该是这样的:
1
这两个更改是添加命名空间,并在null元素上显式设置xsi:nil为true。
如果您无法控制Xml,则可以使用此处描述的更高级技术: 使用XmlSerializer反序列化为Nullable
如果您无法控制入站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很乐意在字符串元素为空时解析它,因此您可以使用它。
这不是特别好,但如果你只有一个或两个标签可以覆盖,那就可以了
为简单起见,为什么不使用XmlDocument和XPath明确解析xml? 使用XPath显式访问每个xml节点,例如
XmlNode node = xml.SelectSingleNode ("foo/PropOne"); if (node != null) { propOneValue = node.innerText; }