2017-09-26 3 views
0

Je suis en train de construire un document CDA par sérialisation mon objet XML, voici la partie XML qui me causer quelques problèmes:L'élément XML « tr » de « » namespace est déjà présent dans la portée actuelle

<component> 
    <section> 
     <templateId root='2.16.840.1.113883.10.20.1.11'/> 
     <templateId root='1.3.6.1.4.1.19376.1.5.3.1.3.6'/> 
     <!--<id root='' extension=''/>--> 
     <code code="11450-4" displayName="PROBLEM LIST" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"/> 
     <title>Active Problem - Problem List</title> 
     <text> 
      <table> 
       <thead> 
        <tr> 
         <th>Problem</th> 
         <th>Code</th> 
         <th>Code System</th> 
         <th>Start Date</th> 
         <th>Status</th> 
        </tr> 
       </thead> 
       <tbody> 
        <tr> 
         <td>Asthma</td> 
         <td>195967001</td> 
         <td>SNOMED CT</td> 
         <td></td> 
         <td>Active</td> 
        </tr> 
        <tr> 
         <td>Costal chondritis</td> 
         <td>64109004</td> 
         <td>SNOMED CT</td> 
         <td></td> 
         <td>Active</td> 
        </tr> 
        <tr> 
         <td>No impairment</td> 
         <td>66557003</td> 
         <td>SNOMED CT</td> 
         <td></td> 
         <td>Active</td> 
        </tr> 
       </tbody> 
      </table> 
     </text> 
    </section> 
</component> 

Et voici mes classes C# pour la sérialisation il:

public class Section 
{ 
    [XmlElement("templateId")] 
    public List<IdElement> TemplateIds { get; set; } 
    [XmlElement("code")] 
    public CodeElement Code { get; set; } 
    [XmlElement("title")] 
    public string Title { get; set; } 
    [XmlElement("text")] 
    public Text Text { get; set; } 
} 
public class Text 
{ 
    [XmlElement("table")] 
    public Table.Table Table { get; set; } 

    [XmlArray("list")] 
    [XmlArrayItem("item")] 
    public List<string> List { get; set; } 

    [XmlElement("paragraph")] 
    public List<string> Paragraphs { get; set; } 
} 
public class Table 
{ 
    [XmlElement("thead")] 
    public TRow Header { get; set; } 
    [XmlElement("tbody")] 
    public TRow Body { get; set; } 
} 
public class TRow 
{ 
    [XmlArray(ElementName = "tr", Namespace = "")] 
    [XmlArrayItem("td")] 
    public List<string> RowData { get; set; } 

    [XmlArray(ElementName = "tr", Namespace = "")] 
    [XmlArrayItem("th")] 
    public List<string> HeaderData { get; set; } 
} 

Mais lorsque je tente de sérialisation mon objet CDA maintenant, il dit que le type tr est déjà présent dans l'espace, donc je suppose que ce genre de tableau XML existe déjà, mais je peux t trouver un moyen de le faire correctement. Y at-il une solution pour contourner ce problème?

Voici le journal des erreurs (sans la trace de la pile):

System.InvalidOperationException: Il y avait une erreur du type réfléchissant 'Project.Cda.Core.ClinicalDocument'. ---> System.InvalidOperationException: Une erreur s'est produite dans la propriété 'Composant'. ---> System.InvalidOperationException: Il y avait une erreur reflétant le type 'Project.Cda.Core.Components.BaseComponent'. ---> System.InvalidOperationException: Une erreur a été détectée lors de la reconnaissance de la propriété 'Composants'. ---> System.InvalidOperationException: était une erreur reflétant le type 'Project.Cda.Core.Components.Component'. ---> System.InvalidOperationException: Une erreur a été détectée en raison de la propriété 'Section'. ---> System.InvalidOperationException: Il y avait une erreur reflétant le type 'Project.Cda.Core.Components.Section'. ---> System.InvalidOperationException: Une erreur s'est produite dans la propriété 'Texte'. ---> System.InvalidOperationException: Une erreur reflétait le type 'Project.Cda.Core.Components.Text'. ---> System.InvalidOperationException: Une erreur s'est produite dans la propriété 'Table'. ---> System.InvalidOperationException: Une erreur reflétait le type 'Project.Cda.Core.Components.Table.Table'. ---> System.InvalidOperationException: Une erreur s'est produite dans la propriété 'En-tête'. ---> System.InvalidOperationException: Il y avait une erreur reflétant le type 'Project.Cda.Core.Components.Table.TRow'. ---> System.InvalidOperationException: Une erreur a renvoyé la propriété 'HeaderData'. ---> System.InvalidOperationException: L'élément XML ' ' de l'espace de noms '' est déjà présent dans la portée actuelle . Utilisez les attributs XML pour spécifier un autre nom XML ou espace de noms pour l'élément .

+2

Dans 'TRow' Vous avez' [XmlArray (ElementName = "tr", Namespace = "")] 'sur' RowData' et 'HeaderData'. Cela ne peut pas fonctionner. – dbc

+0

@dbc Hmm, merci, je vais essayer autre chose. Est-ce que ma seule option est de créer des classes séparées pour les données d'en-tête et de corps? –

+2

C'est de loin le plus facile. Les autres options incluent 1) Utiliser ['[[XmlChoiceIdentifierAttribute]'] (https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlchoiceidentifierattribut (v = vs.110) .aspx) pour configurer un tableau 'enum' indiquant si un élément enfant' 'est un' 'ou' '. 2) Implémenter ['IXmlSerializable'] (https://www.codeproject.com/Articles/43237/Comment-Implémenter-IXmlSerializable-Correctement). (Ne le faites pas!) 3) Faites un tour avec des sérialisations imbriquées dans une propriété '[XmlAnyElement]' comme indiqué par exemple. [ici] (https://stackoverflow.com/a/33180709/3744182). – dbc

Répondre

2

vous obtenez l'erreur parce que, dans TRow, vous avez

[XmlArray(ElementName = "tr", Namespace = "")] 

sur les deux RowData et HeaderData. Cela ne peut pas fonctionner - vous essayez de spécifier le même nom d'élément pour deux propriétés différentes, et ainsi obtenir l'erreur que vous voyez, à savoir que L'élément XML 'tr' de l'espace de noms '' est déjà présent dans la portée actuelle .

En outre, il existe un problème supplémentaire avec vos modèles. Les éléments <tr> à l'intérieur <tbody> se répètent, mais votre modèle de données n'autorise qu'un élément <tr> par corps.

Les correctifs les deux problèmes suivants en introduisant un TablePart intermédiaire pour représenter soit les portions d'en-tête et le corps du tableau:

public class Table 
{ 
    [XmlElement("thead")] 
    public TablePart Header { get; set; } 

    [XmlElement("tbody")] 
    public TablePart Body { get; set; } 
} 

public class TablePart 
{ 
    [XmlElement(ElementName = "tr", Namespace = "")] 
    public List<TableRow> RowData { get; set; } 
} 

public class TableRow 
{ 
    [XmlElement("td")] 
    public List<string> Data { get; set; } 

    [XmlElement("th")] 
    public List<string> Headers { get; set; } 
} 

échantillon fiddle.