无法从 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);
}
我有一个问题,当我尝试读取 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
.
这可能不是最佳选择,但您可以尝试在序列化之前更改文化信息。
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);
}