2011-07-26 25 views
5

Tengo un problema con la deserialización de mis archivos xml. Supongamos que tenemos un archivo xml y una clase que estamos utilizando para la deserialización.XmlSerializer. Omitir xml nodo desconocido

Por ejemplo:

xml -

<dataStore> 
    <name>newDataStore1</name> 
    <description>sdffasdfasdf</description> 
    <type>Shapefile</type> 
    <enabled>false</enabled> 
    <workspace> 
    <name>newTestWorkspace</name> 
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht 
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace.xml" type="app 
lication/xml"/> 
    </workspace> 
    <connectionParameters> 
    <entry key="memory mapped buffer">false</entry> 
    <entry key="create spatial index">true</entry> 
    <entry key="charset">ISO-8859-1</entry> 
    <entry key="filetype">shapefile</entry> 
    <entry key="cache and reuse memory maps">true</entry> 
    <entry key="url">file:data/shapefiles/states.shp</entry> 
    <entry key="namespace">http://www.opengeospatial.net/cite</entry> 
    </connectionParameters> 
    <__default>false</__default> 
    <featureTypes> 
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht 
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace/datastores/new 
DataStore1/featuretypes.xml" type="application/xml"/> 
    </featureTypes> 
</dataStore> 

Clase

namespace GeoServerApiTester 
{ 


    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.225")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute("dataStore", Namespace="", IsNullable=false)] 
    public partial class DataStore 
    { 

     private string nameField; 

     private string typeField; 

     private bool enabledField; 

     private WorkSpacePreview workspaceField; 

     private ConnectionParametersStorageEntryCollection connectionParametersField; 

     private string @__defaultField; 

     private LinkCollection featureTypesField; 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0, ElementName="name")] 
     public string Name 
     { 
      get 
      { 
       return this.nameField; 
      } 
      set 
      { 
       this.nameField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1, ElementName="type")] 
     public string Type 
     { 
      get 
      { 
       return this.typeField; 
      } 
      set 
      { 
       this.typeField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2, ElementName="enabled")] 
     public bool Enabled 
     { 
      get 
      { 
       return this.enabledField; 
      } 
      set 
      { 
       this.enabledField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=3, ElementName="workspace")] 
     public WorkSpacePreview Workspace 
     { 
      get 
      { 
       return this.workspaceField; 
      } 
      set 
      { 
       this.workspaceField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlArrayAttribute(Order=4, ElementName="connectionParameters")] 
     [System.Xml.Serialization.XmlArrayItemAttribute("entry", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)] 
     public ConnectionParametersStorageEntryCollection ConnectionParameters 
     { 
      get 
      { 
       return this.connectionParametersField; 
      } 
      set 
      { 
       this.connectionParametersField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=5)] 
     public string @__default 
     { 
      get 
      { 
       return [email protected]__defaultField; 
      } 
      set 
      { 
       [email protected]__defaultField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlArrayAttribute(Order=6, ElementName="featureTypes")] 
     [System.Xml.Serialization.XmlArrayItemAttribute("link", Namespace="http://www.w3.org/2005/Atom", IsNullable=false)] 
     public LinkCollection FeatureTypes 
     { 
      get 
      { 
       return this.featureTypesField; 
      } 
      set 
      { 
       this.featureTypesField = value; 
      } 
     } 

     public virtual bool ShouldSerializeConnectionParameters() 
     { 
      return ((this.ConnectionParameters != null) 
         && (this.ConnectionParameters.Count > 0)); 
     } 

     public virtual bool ShouldSerializeFeatureTypes() 
     { 
      return ((this.FeatureTypes != null) 
         && (this.FeatureTypes.Count > 0)); 
     } 
    } 
} 

Se puede ver que la clase no contiene campo de descripción.

<dataStore> 
    <name>newDataStore1</name> 
    <enabled>false</enabled> 
</dataStore> 

Puede ver que todos los elementos después de la descripción no se han deserializado.

Cuando el programa obtiene contenido xml y este xml contiene un elemento que no está en la clase, no se desirializarán todos los elementos después de este elemento.

¿Cómo puedo saltar elemento desconocido durante la deserialización y obtener algo como esto:

<dataStore> 
    <name>newDataStore1</name> 

    <type>Shapefile</type> 
    <enabled>false</enabled> 
    <workspace> 
    <name>newTestWorkspace</name> 
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht 
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace.xml" type="app 
lication/xml"/> 
    </workspace> 
    <connectionParameters> 
    <entry key="memory mapped buffer">false</entry> 
    <entry key="create spatial index">true</entry> 
    <entry key="charset">ISO-8859-1</entry> 
    <entry key="filetype">shapefile</entry> 
    <entry key="cache and reuse memory maps">true</entry> 
    <entry key="url">file:data/shapefiles/states.shp</entry> 
    <entry key="namespace">http://www.opengeospatial.net/cite</entry> 
    </connectionParameters> 
    <__default>false</__default> 
    <featureTypes> 
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht 
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace/datastores/new 
DataStore1/featuretypes.xml" type="application/xml"/> 
    </featureTypes> 
</dataStore> 

quitar único elemento

Respuesta

9

Por defecto, el XmlSerializer ignora los nodos desconocidos (por lo que los elementos así). Ahora, cuando usa la propiedad de Orden como lo hace, le está diciendo explícitamente en qué Orden serializar/deserializar.

Así que cuando el XmlSerializer llega a su elemento description, se convierte en un elemento desconocido porque espera el elemento type. El resto también será amenazado como elementos desconocidos porque ya no asignan más a su orden especificada. Por ejemplo, cuando se trata de su elemento type que tiene el índice dos en su XML, espera que sea el elemento enabled, por lo que este elemento se vuelve desconocido también.

Puede controlar este comportamiento controlando el evento UnknownNode de la clase XmlSerializer. Este evento se disparará por cada nodo desconocido que encuentre.

¿Cómo proceder? Si el orden no tiene significado, no lo use. Hay situaciones en las que tiene sentido usar ordenamiento. Un ejemplo clásico que he visto varias veces son aplicaciones (heredadas) que tratan los documentos XML como cadenas y leen todos los elementos de arriba a abajo.

Otra opción sería implementar la interfaz IXmlSerializer, que le da un mejor control sobre cómo se serializa y deserializa su objeto.

+0

¿Es posible omitir los atributos de pedidos sólo para deserialización? –

0

Sé que esto no responde a su pregunta, pero creo que si cambia las direcciones que va a resolver su problema ...

¿Ha creado un XSD para definir el esquema XML? De lo contrario, recomiendo comenzar allí y luego usar xsd2code para crear la clase de serialización.