2016-03-04 1 views
3

je dois linéariser/désérialiser un code XML et une partie de celui-ci ressemble exemple suivant:liste de sérialisation d'objets

<CoordGeom> 
    <Curve rot="cw" chord="830.754618036885" crvType="arc" delta="72.796763873948" dirEnd="283.177582669379" dirStart="355.974346543327" external="169.661846548051" length="889.38025007632" midOrd="136.562611151675" radius="699.999999998612" tangent="516.053996536113"> 
     <Start>4897794.2800513292 6491234.9390137056</Start> 
     <Center>4897096.0071489429 6491185.7968343571</Center> 
     <End>4897255.5861026254 6491867.3645547926</End> 
     <PI>4897758.0514541129 6491749.7197593488</PI> 
    </Curve> 
    <Spiral length="109.418078418008" radiusEnd="INF" radiusStart="699.999999999025" rot="cw" spiType="clothoid" theta="4.477995782709" totalY="2.849307921907" totalX="109.351261203955" tanLong="72.968738862921" tanShort="36.493923980983"> 
     <Start>4897255.5861026254 6491867.3645547936</Start> 
     <PI>4897220.0531303799 6491875.6840722272</PI> 
     <End>4897147.9238984985 6491886.7208634559</End> 
    </Spiral> 
    <Spiral length="153.185309785019" radiusEnd="499.99999999993" radiusStart="INF" rot="ccw" spiType="clothoid" theta="8.776871734087" totalY="7.808812331497" totalX="152.826239431476" tanLong="102.249348442205" tanShort="51.176160975293"> 
     <Start>4897147.9238985004 6491886.7208634559</Start> 
     <PI>4897046.8509311257 6491902.186455016</PI> 
     <End>4896998.0370401107 6491917.5553683294</End> 
    </Spiral> 
    <Curve rot="ccw" chord="936.510896488672" crvType="arc" delta="138.94725576785" dirEnd="66.423714388543" dirStart="287.476458620693" external="925.970149937768" length="1212.543549877849" midOrd="324.680762068264" radius="499.999999999181" tangent="1335.436583485725"> 
     <Start>4896998.0370401107 6491917.5553683294</Start> 
     <Center>4897148.1939981515 6492394.4755796343</Center> 
     <End>4896948.2091376046 6492852.7397562303</End> 
     <PI>4895724.243644949 6492318.6055583945</PI> 
    </Curve> 
</CoordGeom> 

J'ai généré automatiquement à l'aide des classes xsd.exe. Une partie du code généré ressemble à ceci:

public partial class CoordGeom 
    { 
     private List<object> _items; 
     private List<Feature> _feature; 
     private string _desc; 
     private string _name; 
     private stateType _state; 
     private string _oID; 

     public CoordGeom() 
     { 
      _feature = new List<Feature>(); 
      _items = new List<object>(); 
     } 

     [XmlElementAttribute("Chain", typeof(Chain))] 
     [XmlElementAttribute("Curve", typeof(Curve))] 
     [XmlElementAttribute("IrregularLine", typeof(IrregularLine))] 
     [XmlElementAttribute("Line", typeof(Line))] 
     [XmlElementAttribute("Spiral", typeof(Spiral))] 
     public List<object> Items 
     { 
      get { return this._items; } 
      set { this._items = value; } 
     } 

     [XmlElement("Feature")] 
     public List<Feature> Feature { get; set; } 

     [XmlAttribute()] 
     public string desc { get; set; } 

     [XmlAttribute()] 
     public string name { get; set; } 

     [XmlAttribute()] 
     public stateType state { get; set; } 

     [System.Xml.Serialization.XmlAttributeAttribute()] 
     public string oID 
     { 
      get{ return this._oID; } 
      set{ this._oID = value; } 
     } 
    } 

Et mon code pour un look de désérialisation comme ceci:

XmlSerializer mySerializer = new XmlSerializer(typeof(LandXML), new XmlRootAttribute("")); 
TextReader myFileStream = new StreamReader("myFile.xml"); 
LandXML myObject = (LandXML)mySerializer.Deserialize(myFileStream); 
var coordGeomItems = myObject.Alignments.Alignment[0].CoordGeom; 

Mon problème est que, quand je fais deserialize, il est désérialisée liste des articles de type {LandXML.Curve}, {LandXML.Spiral} etc. et je ne sais pas comment accéder à leurs propriétés. Ce serait génial si je peux le faire directement. Voici une capture d'écran:

Debugging screenshot

EDIT 1

Voici l'écran inital enter image description here

j'ai produits

enter image description here

Quand je déplie cette

enter image description here

Et c'est à la couche supérieure de l'objet - il a quelques InnerXml, InnerText ... Si je veux obtenir CoordGeom, il y a beaucoup object.Item (i) .ChildNodes.Item (j) .ChildNodes ...

Et tout cela est parce que dans certaines lignes, des listes d'objets sont faits comme liste que pour CoordGeom

+0

ne pouvez pas vous faire coordGeomItems.Items [0], coordGeomItems .Items [1] etc ?? – Viru

+0

Je suis un peu confus. Où est défini LandXML? Où la propriété Alignments est-elle définie? On dirait qu'il nous manque des informations clés. Peut-être que vous voulez extraire tous les types similaires et effectuer des opérations sur chaque comme: 'coordGeom.Where (x => x est Curve).ToList() '? – xDaevax

+0

@xDaevax Il est défini sur les niveaux supérieurs, le code est trop long pour le forum (le code généré total est> 30k lignes). Ce n'est pas un problème avec les parties précédentes, et c'est pourquoi j'ai posté seulement cette partie. –

Répondre

3

parce qu'il ya plusieurs types autorisés, la collection Items est typée comme objet. L'approche la plus simple consiste à énumérer et jeter chaque élément:

foreach(var item in coordGeomItems.Items) 
{ 
    var curve = item as Curve; 
    if (curve != null) 
    { 
     // access curve properties here 
    } 

    var spiral = item as Spiral 
    if (spiral != null) 
    { 
     // access spiral properties here 
    } 

    // ... 
} 
+0

coordGeomItems est une liste d'éléments (Ce que j'ai vu c'est une liste de types XmlElement) et je ne peux pas exécuter ce code car tous les résultats sont faux. Le problème est dans un moment de création Liste où les objets ne sont pas stockés comme Curve, Spiral etc. mais comme {Element, Name = Curve "} –

+0

Votre code et votre capture d'écran indique le contraire –

+0

Non, vous pouvez voir {} autour de LandXML.Curve L'état normal serait LandXML.Curve sans {} –

1

Vous pouvez construire une liste des courbes et Spirales et d'y accéder en utilisant les propriétés avec getters personnalisées:

class CoordGeom 
{ 
    public List<object> Items; 

    List<Curve> _curves; 
    public List<Curve> Curves 
    { 
     get 
     { 
      return _curves ?? (_curves = Items 
       .Where(item => item is Curve).Select(curve => (Curve)curve).ToList()); 
     } 
    } 
} 

L'opérateur coalescent null (? ?) entraînera la propriété Curves à définir et renvoyer la valeur de _curves sous la forme d'une liste de courbes si _curves est null. Cela lui fait fondamentalement initialiser la liste sur le premier get et sur tous les prochains gets il retournera la liste déjà initialisée.

+0

Je peux, mais alors je perds un ordre d'entre eux, et j'ai besoin de leur ordre dans une liste. Par exemple: c'est important si j'ai une courbe, une spirale, une courbe ou une courbe, une courbe, une spirale –

1

Comme vous ne pouvez pas modifier la classe générée ni le XML. La meilleure approche possible serait d'écrire une méthode d'extension.

public static List<Curve> GetCurves(this CoordGeom cg) 
{ 
return cg.Items.OfType<Curve>().ToList(); 
} 

public static List<Spiral> GetSpirals(this CoordGeom cg) 
{ 
return cg.Items.OfType<Spiral>().ToList(); 
} 

Une fois que vous faites cela, vous pouvez obtenir des articles comme celui-ci

var coordGeomItems = myObject.Alignments.Alignment[0].CoordGeom; 
var curves = coordGeomItems.GetCurves(); 
var spirals = coordGeomItems.GetSpirals(); 
+0

Je dois maintenir l'ordre des courbes et des spirales dans une liste d'objets :( –