I'm trying to deserialize and XML file that is validated to an XSD. But the thing is that one of the nodes can be empty from time to time so I came up with this XSD now
我正在尝试反序列化和验证为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>
The line PrOrNumber can be empty from time to time so I came up with the simpleType int-or-empty. So now when I try to deserialize the XML , it fails when attempting to deserialize the PrOrNumber (returns error input string is not of valid format).
行PrOrNumber可能不时是空的,所以我提出了simpleType int-or-empty。所以现在当我尝试反序列化XML时,它在尝试反序列化PrOrNumber时失败(返回错误输入字符串的格式不正确)。
XML that I'm trying to deserialize
我正在尝试反序列化的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>
And the class that I'm trying to deserialize to
而我正在尝试反序列化的课程
[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; }
}
And the function that does the deserialization
以及进行反序列化的功能
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;
}
What I've tried
我试过的
- Changing the type to integer , decimal etc..
- Changing the type to string
- Commenting the line works but that is not a solution
- Setting the XSD tag on Nillable
将类型更改为整数,十进制等。
将类型更改为字符串
评论该线路有效,但这不是解决方案
在Nillable上设置XSD标记
The thing is I can't change the input XML so adding the xsi:nil="true"
tag is not an option
问题是我无法更改输入XML,因此添加xsi:nil =“true”标签不是一个选项
1 个解决方案
#1
3
I can only get the behaviour you're describing by changing the type of your Log.PrOrNumber property to int or int?, and Kilazur's second link corrects the issue in my reproduction - you're certain you followed through with what it suggested correctly?
我只能通过将Log.PrOrNumber属性的类型更改为int或int?来获取您所描述的行为,而Kilazur的第二个链接更正了我的复制中的问题 - 您确定您正确地遵循了它的建议吗?
In my reproduction case, the serialiser's getting stuck trying to parse an empty string into an integer. To fix, we expose a string property PrOrNumberRaw
for the serialiser to talk to that contains the required parsing logic, and our own property PrOrNumber
with the parse value (or null) for the application to consume.
在我的再现案例中,序列化器试图将空字符串解析为整数。为了解决这个问题,我们为串行器提供了一个字符串属性PrOrNumberRaw,它包含所需的解析逻辑,以及我们自己的属性PrOrNumber,其中包含应用程序要使用的解析值(或null)。
The Log class definition changes to become:
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; }
}
#1
3
I can only get the behaviour you're describing by changing the type of your Log.PrOrNumber property to int or int?, and Kilazur's second link corrects the issue in my reproduction - you're certain you followed through with what it suggested correctly?
我只能通过将Log.PrOrNumber属性的类型更改为int或int?来获取您所描述的行为,而Kilazur的第二个链接更正了我的复制中的问题 - 您确定您正确地遵循了它的建议吗?
In my reproduction case, the serialiser's getting stuck trying to parse an empty string into an integer. To fix, we expose a string property PrOrNumberRaw
for the serialiser to talk to that contains the required parsing logic, and our own property PrOrNumber
with the parse value (or null) for the application to consume.
在我的再现案例中,序列化器试图将空字符串解析为整数。为了解决这个问题,我们为串行器提供了一个字符串属性PrOrNumberRaw,它包含所需的解析逻辑,以及我们自己的属性PrOrNumber,其中包含应用程序要使用的解析值(或null)。
The Log class definition changes to become:
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; }
}