2011-12-11 28 views
7

que estoy tratando de deserializar un objeto Movie de un "alemán" cadena XML:XML-Deserialización de valor doble con separador decimal alemán en 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); 

aquí la clase Movie para referencia:

[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(); 
    } 

} 

siempre que puse un <price> como 1.99 funciona perfectamente. cuando uso el separador decimal alemán alemán 1,99 ya no funciona.

Por favor, consejos

+3

¿Tiene un esquema asociado? En la especificación XML-Schema, un doble debe representarse con a. http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#decimal, por lo que este comportamiento es por diseño. Puede reemplazar el tipo de Precio por una cadena y luego tener una propiedad no-especializada Realprice que use una Double.Parse con una cadena de formato adecuada – rene

+0

El xml me es dado en este formato y no puedo hacer nada al respecto. pero gracias por tu respuesta! –

+1

Nota importante: los valores de las monedas casi siempre deben ser decimales, no dobles –

Respuesta

7

Como ya se indicó, simplemente no es una forma válida de representar un valor numérico en XML. Sin embargo, está bien para una cuerda. Se podría hacer:

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

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

donde "..." representa su opción de formato que especifica y el CultureInfo

+0

en mi caso CultureInfo.GetCultureInfo ("de-DE")).Formato numérico –

1

Como se ha mencionado, el XmlSerializer no es la herramienta adecuada para usted, ya que se va a utilizar la especificación del esquema W3C tipo de datos.

Las soluciones alternativas incluyen el uso de un archivo XSLT para convertir el XML de entrada antes de la deserialización, o el uso de otra herramienta como Linq a XML.

+0

¿Puede darnos una muestra, por favor? –

+2

http://stackoverflow.com/questions/647991/summing-numbers-with-comma-as-decimal-separator-in-xslt puede darle algunas ideas para la traducción – devdigital

3

En el XML Schema inspeccionar el double/decimal necesidades de ser representado con una . por lo que este comportamiento es por diseño .

Puede reemplazar el tipo de Precio por cadena y luego tener una propiedad no serializada Realprice que utiliza un Double.TryParse con un CultureInfo o NumberFormatInfo apropiado.

[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; 
       } 
     } 
Cuestiones relacionadas