无法从 XML 读取小数

Unable to read decimal numbers from XML

我有一个问题,当我尝试读取 XML 文件时,该文件具有十进制值,例如 24.5478785 - 它返回错误:

There is error in XML document

谁能指点一下,为什么会这样?文件中的小数部分如下所示:<interval>22,555555</interval>

我的代码:

private void OpenFileXml(bool runIt, string file)
{
    //Get data from XML file
    XmlSerializer ser = new XmlSerializer(typeof(ActionsEntry));
    using (FileStream fs = System.IO.File.Open(file, FileMode.Open))
    {
        try
        {
            ActionsEntry entry = (ActionsEntry)ser.Deserialize(fs);
            lvActions.Items.Clear();
            foreach (ActionsEntryAction ae in entry.Action)
            {
                string point = ae.X.ToString() + "," + ae.Y.ToString();
                string interval = (ae.interval).ToString("F6");
                ListViewItem lvi = new ListViewItem(new string[] { point, ((ClickType)(ae.Type)).ToString(), interval, ae.Text });
                ActionEntry acion = new ActionEntry(ae.X, ae.Y, ae.Text, ae.interval, (ClickType)(ae.Type));
                lvi.Tag = acion;
                lvActions.Items.Add(lvi);
            }

            if (runIt)
            {
                btnStart.PerformClick();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Clicer", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

编辑

XML 文件:

XML:

<?xml version="1.0" encoding="utf-8"?><ActionsEntry xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Action>
<X>824</X>
<Y>456</Y>
<Text />
<interval>22,555555</interval>
<Type>0</Type>
</Action>
</ActionsEntry>

XML 序列化程序对 serialize/deserialize float/date 时间使用标准格式,它实际上并不关心 CultureInfo。这个问题是由于线程的 cultureInfo.

中的 float 转换引起的

这可能不是最佳选择,但您可以尝试在序列化之前更改文化信息。

System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
customCulture.NumberFormat.NumberDecimalSeparator = ",";

System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;

或者您可以实现自定义序列化程序。这是一篇不错的文章

Injecting XML Serialization for formatting decimal properties

另一种选择是更改ActionsEntry class 并实现包装器属性 以转换interval 并忽略thread's cultureInfo 以解决此问题。

public class ActionsEntry
{
    public Action Action { get; set; }
}

public class Action
{
    public int X { get; set; }

    public int Y { get; set; }

    public string Text { get; set; }

    [XmlIgnore]
    public float interval { get; set; }

    private string _intervalString;
    [XmlElement("interval")]
    public string IntervalString
    {
        get
        {
            return _intervalString;
        }
        set
        {
            _intervalString = value;
            if (!string.IsNullOrEmpty(value))
            {
                interval = float.Parse(value, CultureInfo.InvariantCulture);
            }
        }
    }

    public int Type { get; set; }
}

You have not provided the structure of your Action and ActionsEntry classes, so I went ahead with following assumptions

public class ActionsEntry
    {
        public ActionsEntry() { Actions = new List<Action>(); }
        [XmlElement("Action")]
        public List<Action> Actions { get; set; }

    }

    public class Action
    {
        public int X { get; set; }
        public int Y { get; set; }

        public string Text { get; set; }

        [XmlElement("interval")]
        public string Interval { get; set; }
        public int Type { get; set; }

    }

然后,在我尝试的 for 循环中:

ActionsEntry entry = (ActionsEntry)ser.Deserialize(fs);
foreach (var action in entry.Actions)
{
    string interval = action.Interval.Replace(',', '.');
    decimal intvrl = Decimal.Parse(interval);
    Console.WriteLine(intvrl);
}