我目前的任务涉及编写一个用于处理HL7 CDA文件的类库。
这些HL7 CDA文件是具有已定义XML模式的XML文件,因此我使用xsd.exe为XML序列化和反序列化生成.NET类。.NET中“混合”类型的正确XML序列化和反序列化
XML模式包含各种类型,其中包含mixed =“true”属性,指定此类型的XML节点可能包含与其他XML节点混合的普通文本。
的XML模式的这些类型之一的相关部分看起来是这样的:
<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>
的产生这种类型的代码看起来是这样的:
/// <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...
}
如果我反序列化一个XML元素,其段落节点如下所示:
<paragraph>first line<br /><br />third line</paragraph>
的结果是该项目和文本阵列读这样的:
itemsField = new object[]
{
new StrucDocBr(),
new StrucDocBr(),
};
textField = new string[]
{
"first line",
"third line",
};
从这个是没有可能的方式来确定文本和其他节点的确切顺序。
如果我再次序列化此,结果看起来就像这样:
<paragraph>
<br />
<br />first linethird line
</paragraph>
默认串行只是先序列化的项目的文本。
我试图在StrucDocParagraph类实现IXmlSerializable
,这样我可以控制内容的反序列化和序列化,但它是相当复杂的,因为有参与了很多课,我没来解决但因为我不不知道付出的努力是否值得。
是否有某种容易的解决方法到这个问题,或者它甚至可以通过自定义序列化通过IXmlSerializable
? 或者我应该只使用XmlDocument
或XmlReader
/XmlWriter
来处理这些文件?
这似乎不工作了(我的System.Xml版本是4.0.0)问题是它通过ItemsElementName字符串数组跟踪Items数组中元素的名称,并且元素必须匹配1对1 。如果您正在通过反序列化XML文档填充的对象模型进行工作,则此要求会导致错误,因为XMLSerializer不会为其ItemsElementName数组中放置代表性条目。所以一个文本节点后跟一个xml元素后跟一个文本节点会导致Items数组中有3个条目,但在ItemsElementName中只有1个条目。 – shahzbot 2017-10-30 20:25:19