Duplicado:

Omitiendo todos los espacios de nombres xml cuando serializar un objeto?
No es el mismo.. quiero en la otra forma: Deserializar!


Tengo una clase de C# como el bramido:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.portalfiscal.inf.br/nfe")]
[System.Xml.Serialization.XmlRootAttribute("NFe", Namespace = "http://www.portalfiscal.inf.br/nfe", IsNullable = false)]
public partial class TNFe
{

    private TNFeInfNFe infNFeField;

    private SignatureType signatureField;

    ///<remarks/>
    public TNFeInfNFe infNFe
    { ...

Puedo usar esta clase para serializar/deserializar los archivos XML por solicitud del usuario.
Pero tengo un problema: definición de espacios de nombres se han añadido en la nueva versión de este software.
El XML es todavía el mismo, sólo que añadiendo espacios de definición.

Ej., la última versión…

<?xml version="1.0" encoding="utf-8" ?>
  <NFe>
    <infNFe version="1.10">
      ...

y la nueva versión de…

<?xml version="1.0" encoding="utf-8" ?> 
  <NFe xmlns="http://www.portalfiscal.inf.br/nfe">
    <infNFe version="2.10">
      ...

Tengo que cargar los archivos XML con y sin estos espacios de nombres.
Tengo un montón de clases anidadas y cada una de ella tiene su propia definición de espacios de nombres.

Me gustaría utilizar las mismas clases para ambos XML, con y sin espacios de nombres.

Traté de crear un XmlTextReader y sobrescribir el NamespaceURI método, pero yo todavía recibe una excepción y no hay mucha info. Creo que .NETA del motor está tratando de forzar a la clase de definición del espacio de nombres contra el XML.

  • Hola, es la consulta resuelto?
  • Arijit, he resuelto utilizando un enfoque diferente. Desafortunadamente, no hay manera de hacer lo que yo quería de la manera que yo quería (con menos código como sea posible). Así que he usado la clase XmlTextReader para algunos servicios web y en otras no serializado todo el Xml en una cadena y se retira la parte no utilizada de los espacios de nombres mediante el uso de de la Cadena.Reemplace. No es la mejor cosa nunca, pero ha demostrado ser buena también.
  • Gracias por la respuesta, bueno en realidad mi problema es algo similar a usted, la respuesta dada a continuación no es de trabajo, supongo. Se puede mostrar cómo lo hizo? Es de 4 años ¿por qué microsoft no pensaba en ella?
InformationsquelleAutor rodrigogq | 2010-02-19

4 Comentarios

  1. 7

    Me había quedado en un problema similar con una clase de proxy. Por razones que no voy a entrar, yo necesarios para serializar la clase de forma manual utilizando la clase XmlSerializer en el servidor web y deserializar en el cliente. Yo no era capaz de encontrar una solución elegante en línea, por lo que me acaba de evitar el problema mediante la eliminación de la XmlTypeAttribute de la clase de proxy manualmente después de que me auto-generado en Visual Studio.

    Yo volvía a ver si había una manera de conseguir que el espacio de nombres de entrenamiento. Aquí es cómo yo tengo trabajo sin la necesidad de modificar las clases auto-generadas. Terminé usando un XmlTextReader para devolver el espacio de nombres que desee en los nodos que coinciden con un nombre de propiedad. Hay espacio para la mejora, pero espero que ayude a alguien.

    class Program
    {
    static void Main(string[] args)
    {
    //create list to serialize
    Person personA = new Person() { Name = "Bob", Age = 10, StartDate = DateTime.Parse("1/1/1960"), Money = 123456m };
    List<Person> listA = new List<Person>();
    for (int i = 0; i < 10; i++)
    {
    listA.Add(personA);
    }
    //serialize list to file
    XmlSerializer serializer = new XmlSerializer(typeof(List<Person>));
    XmlTextWriter writer = new XmlTextWriter("Test.xml", Encoding.UTF8);
    serializer.Serialize(writer, listA);
    writer.Close();
    //deserialize list from file
    serializer = new XmlSerializer(typeof(List<ProxysNamespace.Person>));
    List<ProxysNamespace.Person> listB;
    using (FileStream file = new FileStream("Test.xml", FileMode.Open))
    {
    //configure proxy reader
    XmlSoapProxyReader reader = new XmlSoapProxyReader(file);
    reader.ProxyNamespace = "http://myappns.com/";      //the namespace of the XmlTypeAttribute 
    reader.ProxyType = typeof(ProxysNamespace.Person); //the type with the XmlTypeAttribute
    //deserialize
    listB = (List<ProxysNamespace.Person>)serializer.Deserialize(reader);
    }
    //display list
    foreach (ProxysNamespace.Person p in listB)
    {
    Console.WriteLine(p.ToString());
    }
    Console.ReadLine();
    }
    }
    public class Person
    {
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime StartDate { get; set; }
    public decimal Money { get; set; }
    }
    namespace ProxysNamespace
    {
    [XmlTypeAttribute(Namespace = "http://myappns.com/")]
    public class Person
    {
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime Birthday { get; set; }
    public decimal Money { get; set; }
    public override string ToString()
    {
    return string.Format("{0}:{1},{2:d}:{3:c2}", Name, Age, Birthday, Money);
    }
    }
    }
    public class XmlSoapProxyReader : XmlTextReader
    {
    List<object> propNames;
    public XmlSoapProxyReader(Stream input)
    : base(input)
    {
    propNames = new List<object>();
    }
    public string ProxyNamespace { get; set; }
    private Type proxyType;
    public Type ProxyType
    {
    get { return proxyType; }
    set
    {
    proxyType = value;
    PropertyInfo[] properties = proxyType.GetProperties();
    foreach (PropertyInfo p in properties)
    {
    propNames.Add(p.Name);
    }
    }
    }
    public override string NamespaceURI
    {
    get
    {
    object localname = LocalName;
    if (propNames.Contains(localname))
    return ProxyNamespace;
    else
    return string.Empty;
    }
    }
    }
    • Hola Cristal, yo casi estoy en un problema similar, necesitas ayuda
    • Brillante el Jabón lector de proxy –> se agradece un montón.
  2. 8

    Para deserializar espacio de nombres XML sin añadir XmlRoot atributo a la clase que representa la parte superior de la jerarquía:

    [XmlRoot(ElementName="plugins", Namespace="")]

    En mi ejemplo el Xml no tiene ningún espacio de nombres y comienza como

    <plugins><...

    La clase a la que deserializa a:

    [XmlRoot(ElementName="plugins", Namespace="")]
    public class Plugins
    {
    //...
    }

    Obviamente, su situación puede ser un poco diferente, pero este código me funciona:

    using (FileStream stream = File.Open(filePath, FileMode.Open))
    {
    XmlReader reader = new XmlTextReader(stream);                
    XmlSerializer serializer = new XmlSerializer(typeof(Plugins));
    var plugins = (Plugins)serializer.Deserialize(reader);
    }

    -Stan

  3. 1

    Usted puede leer el archivo de texto, eliminar el consumo de espacio de nombres del texto, a continuación, deserializar ella.

    Usted puede necesitar para escribir el «buen» fondo de texto en un [memory/cadena/etc] secuencia, de modo que la clase XmlSerializer del Deserializar puede ser llamado.

    • Sí… esta parece ser la «mejor» manera. Tks!
  4. -1

    Que usted necesita para implementar IXmlSerializable para mejorar su serialización personalizada.

    • Tengo un montón de clases anidadas. Sería terrible para implementar en cada una de estas clases sólo para eliminar los espacios de nombres!!!! Yo tendría que agregar un XmlSchemaProvider para cada clase, volviendo esquemas diferentes dependiendo de la versión. No hay una manera más fácil de hacer deserializar? Como la adición de un espacio de nombres vacío de la cadena a la función serialize?

Dejar respuesta

Please enter your comment!
Please enter your name here