我正在尝试反序列化和验证为XSD的XML文件。但问题是其中一个节点可能不时是空的,所以我现在想出了这个XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="InterfaceLog">
<xs:complexType>
<xs:sequence>
<xs:element name="Log" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="InterfaceID" type="xs:string"/>
This line --> <xs:element name="PrOrNumber" type="int-or-empty"/>
<xs:element name="MESKey" type="xs:string"/>
<xs:element name="MsgStatusCode" type="xs:string"/>
<xs:element name="MsgClass" type="xs:string"/>
<xs:element name="MsgNumber" type="xs:string"/>
<xs:element name="MsgDescription" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="int-or-empty">
<xs:union memberTypes="xs:int empty-string" />
</xs:simpleType>
<xs:simpleType name="empty-string">
<xs:restriction base="xs:string">
<xs:enumeration value="" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
PrOrNumber行可能不时是空的,所以我提出了simpleType int-or-empty。所以现在当我尝试反序列化XML时,它在尝试反序列化PrOrNumber时失败(返回错误输入字符串的格式不正确)。
我正在尝试反序列化的XML
<?xml version="1.0" encoding="utf-8" ?>
<ns2:InterfaceLog xmlns:ns2="foo.com/foo">
<Log>
<InterfaceID>InterFace_Id</InterfaceID>
<PrOrNumber/>
<MESKey>Run</MESKey>
<MsgStatusCode>S</MsgStatusCode>
<MsgClass>Class</MsgClass>
<MsgNumber>123</MsgNumber>
<MsgDescription>Description</MsgDescription>
</Log>
</ns2:InterfaceLog>
我正在尝试反序列化的课程
[XmlRoot("InterfaceLog", Namespace = "foo.com/foo")]
[Serializable]
public class InterfaceLog
{
[XmlElement("Log", Namespace = "")]
public List<Log> LogCollection { get; set; }
}
[XmlRoot("Log")]
[Serializable]
public class Log
{
public Log() { }
[XmlElement("InterfaceID")]
public string InterfaceID { get; set; }
[XmlElement("PrOrNumber")]
public string PrOrNumber { get; set; }
[XmlElement("MESKey")]
public string MESKey { get; set; }
[XmlElement("MsgStatusCode")]
public string MsgStatusCode { get; set; }
[XmlElement("MsgClass")]
public string MsgClass { get; set; }
[XmlElement("MsgNumber")]
public string MsgNumber { get; set; }
[XmlElement("MsgDescription")]
public string MsgDescription { get; set; }
}
执行反序列化的函数
InterfaceLog interfaceLogCollection = xmlString.Deserialize<InterfaceLog>();
public static T Deserialize<T>(this string serializedObj) where T : class
{
XmlSerializer xs = new XmlSerializer(typeof(T));
T result;
using (TextReader reader = new StringReader(serializedObj))
result = xs.Deserialize(reader) as T;
return result;
}
我尝试了什么
问题是我无法更改输入XML,因此添加xsi:nil="true"
标签不是一个选项
答案 0 :(得分:3)
我只能通过将Log.PrOrNumber属性的类型更改为int或int?来获取您描述的行为,而Kilazur's second link更正了我的复制中的问题 - 您确定你是否正确地遵循了它的建议?
在我的复制案例中,序列化器试图将空字符串解析成整数。为了解决这个问题,我们为串行器提供了一个字符串属性PrOrNumberRaw
,它包含所需的解析逻辑,以及我们自己的属性PrOrNumber
,其中包含应用程序要使用的解析值(或null)。
Log类定义变为:
[XmlRoot("Log")]
[Serializable]
public class Log
{
public Log() { }
[XmlElement("InterfaceID")]
public string InterfaceID { get; set; }
[XmlElement("MESKey")]
public string MESKey { get; set; }
[XmlElement("MsgStatusCode")]
public string MsgStatusCode { get; set; }
[XmlElement("MsgClass")]
public string MsgClass { get; set; }
[XmlElement("MsgNumber")]
public string MsgNumber { get; set; }
[XmlElement("MsgDescription")]
public string MsgDescription { get; set; }
[XmlElement("PrOrNumber")]
public string PrOrNumberRaw
{
get { return this.PrOrNumber.ToString(); }
set
{
if (!string.IsNullOrWhiteSpace(value))
{
this.PrOrNumber = int.Parse(value);
}
else
{
this.PrOrNumber = null;
}
}
}
[XmlIgnore]
public int? PrOrNumber { get; set; }
}