2011-12-11 5 views
7

я пытаюсь десериализацией Movie объекта от «немецкой» Строки XML:XML-Десериализация двойного значения с немецким десятичным разделителем в C#

string inputString = "<?xml version=\"1.0\"?>" 
    + "<movie title=\"Great Bollywood Stuff\">" 
    + "<rating>5</rating>" 
    + "<price>1,99</price>" // <-- Price with German decimal separator! 
    + "</movie>"; 

XmlSerializer movieSerializer = new XmlSerializer(typeof(Movie)); 
Movie inputMovie; 

using (StringReader sr = new StringReader(inputString)) 
{ 
    inputMovie = (Movie)movieSerializer.Deserialize(sr); 
} 
System.Console.WriteLine(inputMovie); 

здесь Movie класса для справки:

[XmlRoot("movie")] 
public class Movie 
{ 

    [XmlAttribute("title")] 
    public string Title { get; set; } 

    [XmlElement("rating")] 
    public int Rating { get; set; } 

    [XmlElement("price")] 
    public double Price { get; set; } 

    public Movie() 
    { 

    } 

    public Movie(string title, int rating, double price) 
    { 
     this.Title = title; 
     this.Rating = rating; 
     this.Price = price; 
    } 

    public override string ToString() 
    { 
     StringBuilder sb = new StringBuilder("Movie "); 
     sb.Append("[Title=").Append(this.Title); 
     sb.Append(", Rating=").Append(this.Rating); 
     sb.Append(", Price=").Append(this.Price); 
     sb.Append("]"); 

     return sb.ToString(); 
    } 

} 

как долго я положил <price> как 1.99, он отлично работает. когда я использую немецкий немецкий десятичный разделитель 1,99, он больше не работает.

пожалуйста совет

+3

У вас есть схема связи? В спецификации XML-Schema двойной должен быть представлен с помощью. http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#decimal, поэтому это поведение по дизайну. Вы можете заменить тип цены на строку, а затем иметь несериализованное свойство Realprice, которое использует Double.Parse с подходящим форматированием string – rene

+0

xml предоставляется мне в этом формате, и я ничего не могу с этим поделать. но спасибо за ваш ответ! –

+1

Важное примечание: значения валюты должны быть почти всегда десятичными, а не двойными –

ответ

7

Как уже отмечалось, это просто недействительный способ представления числового значения в XML. Это нормально для строки. Вы можете сделать:

[XmlIgnore] 
public decimal Price {get;set;} 

[XmlElement("price")] 
public string PriceFormatted { 
    get { return Price.ToString(...); } 
    set { Price = decimal.Parse(value, ...); } 
} 

Где «...» представляет свой выбор спецификатора формата и CultureInfo

+0

в моем случае CultureInfo.GetCultureInfo ("de-DE") .NumberFormat –

1

Как уже упоминалось, XmlSerializer не является правильным инструментом для вас, потому что он собирается использовать спецификацию W3C схемы типа данных.

Альтернативные решения включают использование XSLT-файла для преобразования входного XML перед десериализацией или с использованием другого инструмента, такого как Linq to XML.

+0

Можете ли вы дать образец, пожалуйста? –

+2

http://stackoverflow.com/questions/647991/summing-numbers-with-comma-as-decimal-separator-in-xslt может дать вам некоторые идеи для перевода – devdigital

3

В XML-схемы ЗресЛ double/decimal потребности быть представлены с . так это поведение является ,

Вы можете заменить тип цены на строку и затем иметь несериализованное свойство Realprice, которое использует Double.TryParse с соответствующими CultureInfo или NumberFormatInfo.

[XmlRoot("movie")] 
public class Movie {  
     [XmlElement("price")]  
     public string Price { get; set; } 

     [XmlIgnore] 
     public double RealPrice { 
     get { 
       double resultprice; 
       if (!Double.TryParse(
        Price, 
        NumberStyles.Any, 
        new CultureInfo("de-DE"), 
        resultprice)) throw new ArgumentException("price"); 
       // resultprice is now parsed, if not an exception is thrown 
       return resultprice; 
       } 
     }