Mi tarea actual consiste en escribir una biblioteca de clase para procesar archivos HL7 CDA.
Estos archivos HL7 CDA son archivos XML con un esquema XML definido, así que usé xsd.exe para generar clases .NET para la serialización y deserialización de XML.Corregir serialización XML y deserialización de tipos "mixtos" en .NET
El esquema XML contiene varios tipos que contienen el atributo mixed = "true", que especifica que un nodo XML de este tipo puede contener texto normal mezclado con otros nodos XML.
La parte pertinente del esquema XML para uno de estos tipos tiene el siguiente aspecto:
<xs:complexType name="StrucDoc.Paragraph" mixed="true">
<xs:sequence>
<xs:element name="caption" type="StrucDoc.Caption" minOccurs="0"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="br" type="StrucDoc.Br"/>
<xs:element name="sub" type="StrucDoc.Sub"/>
<xs:element name="sup" type="StrucDoc.Sup"/>
<!-- ...other possible nodes... -->
</xs:choice>
</xs:sequence>
<xs:attribute name="ID" type="xs:ID"/>
<!-- ...other attributes... -->
</xs:complexType>
El genera el código de este tipo se parece a esto:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(TypeName="StrucDoc.Paragraph", Namespace="urn:hl7-org:v3")]
public partial class StrucDocParagraph {
private StrucDocCaption captionField;
private object[] itemsField;
private string[] textField;
private string idField;
// ...fields for other attributes...
/// <remarks/>
public StrucDocCaption caption {
get {
return this.captionField;
}
set {
this.captionField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("br", typeof(StrucDocBr))]
[System.Xml.Serialization.XmlElementAttribute("sub", typeof(StrucDocSub))]
[System.Xml.Serialization.XmlElementAttribute("sup", typeof(StrucDocSup))]
// ...other possible nodes...
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Text {
get {
return this.textField;
}
set {
this.textField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(DataType="ID")]
public string ID {
get {
return this.idField;
}
set {
this.idField = value;
}
}
// ...properties for other attributes...
}
Si deserializar un elemento XML donde el nodo del párrafo se ve así:
<paragraph>first line<br /><br />third line</paragraph>
El resultado es que las matrices de elementos y de texto se leen así:
itemsField = new object[]
{
new StrucDocBr(),
new StrucDocBr(),
};
textField = new string[]
{
"first line",
"third line",
};
De esto no hay manera posible de determinar el orden exacto del texto y los demás nodos.
Si serializar esto de nuevo, el resultado se ve exactamente como esto:
<paragraph>
<br />
<br />first linethird line
</paragraph>
El serializador predeterminado simplemente serializa los artículos primero y luego el texto.
Intenté implementar IXmlSerializable
en la clase StrucDocParagraph para poder controlar la deserialización y serialización del contenido, pero es bastante complejo ya que hay tantas clases involucradas y no he llegado a una solución porque no lo hago Saber si el esfuerzo vale la pena.
¿Existe algún tipo de solución fácil a este problema, o incluso es posible mediante la serialización personalizada a través de IXmlSerializable
? ¿O debería usar XmlDocument
o XmlReader
/XmlWriter
para procesar estos documentos?
Esto parece no funcionar más (mi versión de System.Xml es 4.0.0) El problema es que rastrea los nombres de los elementos en la matriz Elementos a través de una matriz de cadena ItemsElementName y los elementos deben coincidir 1-a-1 . Este requisito genera un error si está trabajando desde un modelo de objeto que ha rellenado al deserializar un documento XML, porque el XMLSerializer no coloca entradas representativas en la matriz ItemsElementName para ellos. Por lo tanto, un nodo de texto seguido de un elemento xml seguido de un nodo de texto genera 3 entradas en su matriz Elementos, pero solo 1 en ItemsElementName. – shahzbot