输入字符串的格式不正确。

4

我正在尝试对已验证为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这一行有时可能为空,因此我想到了使用简单类型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;
    }

我尝试了以下方法:

  • 将类型更改为整数、小数等……
  • 将类型更改为字符串
  • 注释该行可行,但这不是一个解决方案
  • 将XSD标签设置为Nillable

问题在于我无法更改输入的XML,因此添加xsi:nil="true"标签不是一个选项。


请使用属性nillable或use,允许元素类型为整数或空。 - Kilazur
嗯,那个https://dev59.com/KHvZa4cB1Zd3GeqP-hFr怎么样? - Kilazur
还是同样的错误。 - Nicolas Pierre
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
3

我只能通过将你的Log.PrOrNumber属性的类型更改为int或int?来获得你描述的行为,而 Kilazur的第二个链接纠正了我的复制问题 - 你确定你正确地按照它建议的去做了吗?

在我的复制案例中,序列化程序卡在尝试将空字符串解析为整数时。要解决此问题,我们公开一个名为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; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,