2012-07-17 26 views
10

estoy usando XDocument para crear un archivo XML, de la siguiente manera:Cómo crear XElement fecha en representación de fecha y hora como tipo xs: Fecha

var d = DateTime.Now; 

var xDocument = new XDocument(new XElement("ThisIsADate", d)); 

Sin embargo, el XML resultante representa la fecha d el uso de los xs: formato de fecha y hora (por ejemplo, "2012-05-11T00: 00: 00"). Es decir, incluye información de tiempo.

Sin embargo, mi XML está destinado a coincidir con mi esquema XML, que define el elemento como de tipo "xs: date". En consecuencia, el archivo se rechaza cuando se valida con el esquema, debido a la información de tiempo extra.

¿Cómo puedo solucionar esto? Sé que podría simplemente formatear la fecha usando ToString() con un formato, pero esta no puede ser la forma "correcta" de hacerlo, seguramente. No se puede esperar que sepa cómo formatear una fecha como una fecha XML válida: ese es el trabajo de las partes del marco relacionadas con XML.


Editar: Tenga en cuenta que yo hago saben cómo dar formato a una fecha con ToString(), y también sé qué cadena de formato me daría el resultado correcto. Esa no es la respuesta que estoy buscando. Estoy buscando una función/método/clase que entienda qué es xs: date (etc.), y que admita ese tipo de codificaciones.

Para ser claro, no estoy buscando "hacerlo bien", estoy buscando "hacerlo bien". Y reinventar la rueda XML no es "hacerlo bien" en mi libro.

+1

creo que tendría que especificar el formato usando 'ToString()' lo demás es sólo convertir el objeto que se pasa a su variante de cadena por el '.ToString()' por lo que tendrá que pasar en la costumbre formato – V4Vendetta

Respuesta

5

Como ya se ha señalado, LINQ to XML no puede generar un valor DateTime con el formato xs:date. A DateTime viajes de ida y vuelta en LINQ a XML utilizando el formato xs:dateTime y.NET no tiene un tipo de fecha solamente, por lo que no es una sorpresa que los diseñadores de LINQ a XML decidieron usar solo xs:dateTime para no complicar la API.

La única opción es formatear la fecha como una cadena que le da control total del formato. Para utilizar correctamente el formato xs:date que necesita para convertir el DateTime a una cadena utilizando este código:

d.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) 

Usando ToShortDateString y/o no especificar una CultureInfo no producirá el resultado deseado.

0

Parece haber confusión XML o como tal, XElement almacenará el valor como una cadena. Lo que se almacena es más un trabajo del Xml Schema Validator.

Por lo tanto, cuando tenga que representar Date, deberá pasar la versión de cadena de la parte Fecha, puede usar el ToShortDateString() o el formato personalizado en ToString().

Cuando está pasando la instancia de DateTime solo llama al ToString() que también contiene el componente Time.

Espero que esto te ayude.

+0

Entiendo que XElement almacena una cadena. Mi pregunta es, sin embargo, cómo crear la cadena sin recurrir a una cadena de formato codificada. Debe haber una función dentro del espacio de nombres X ... para hacer esto por mí? –

0

A DateTimealways tiene componentes de fecha y hora. Entonces, el truco es decir DateTime para dar salida solo a su componente de fecha. Cuando reconstituya la fecha en el extremo receptor, la hora predeterminada será la medianoche.

var XDocument = new XDocument(new XElement("ThisIsADate", DateTime.Now.ToShortDateString())); 

La forma predeterminada es M/d/yyyy, pero todavía no puede estar en el formato correcto! No sé lo que espera tu esquema.

Así que utilice ToString("yourFormatStringHere")

var XDocument = new XDocument(new XElement("ThisIsADate", DateTime.Now.ToString("M-dd-yyyy"))); 

Si desea obtener realmente de lujo, es decir, escribir código robusto ... Tire de la cadena de formato de su documento de esquema y de referencia que en el método ToString() en lugar de tener una cadena de formato explícita pero redundante.

+0

Gracias, pero como "dije" a V4Vendetta, no creo que sea apropiado para mí tener que saber cómo formatear correctamente una fecha XML. Quiero decir, * sé * cómo (aaaa-MM-dd), pero no creo que una API de creación de XML esté completa sin tener una función para hacer esto. Así que estoy bastante seguro de que habrá una función para hacer esto en alguna parte, y mi pregunta es simplemente "¿dónde?". –

+1

Y para el registro, la forma de una xs: date no está definida por mi esquema, sino por el W3C :-) –

+0

Tal vez 'XmlReader.ReadAsDateTime()' funcionará. De forma predeterminada, esto intenta utilizar DateTime (ing) según las reglas de W3C. – radarbob

2

me fijo este problema utilizando la siguiente clase de DateElements

private class XDateElement : XElement 
{ 
    public XDateElement(XName name, DateTime Date) : 
    base(name, Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)) 
    { } 
} 

La ventaja de usar una clase como esta es, que tiene la conversión de la fecha específica en un solo lugar.

var d = DateTime.Now; 
var xDocument = new XDocument(new XDateElement("ThisIsADate", d));