如何反序列化/序列化Microlife';c#中的xml
本文关键字:中的 xml Microlife 反序列化 序列化 | 更新日期: 2023-09-27 18:28:00
当我需要处理特定的xml文件时,我通常使用xsd2code生成c#类。但现在我有一个奇怪的xml文件被Microlife的血压分析器使用。xml文件将其模式作为额外的第一个元素包含在内部,如本例
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Patient">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" default="">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="11"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="FamilyName" type="xs:string" default="" minOccurs="0"/>
<xs:element name="GivenNames" type="xs:string" default="" minOccurs="0"/>
<xs:element name="Address" type="xs:string" default="" minOccurs="0"/>
<xs:element name="PhoneEmail" type="xs:string" default="" minOccurs="0"/>
<xs:element name="DateOfBirth" type="xs:dateTime" minOccurs="0"/>
<xs:element name="Weight" type="xs:decimal" default="0" minOccurs="0"/>
<xs:element name="Height" type="xs:decimal" default="0" minOccurs="0"/>
<xs:element name="Sex" type="xs:int" default="-1" minOccurs="0"/>
<xs:element name="Smoker" type="xs:int" default="-1" minOccurs="0"/>
<xs:element name="Diabetic" type="xs:int" default="-1" minOccurs="0"/>
<xs:element name="Cholestrol" type="xs:decimal" default="0" minOccurs="0"/>
<xs:element name="FamilyHistory" type="xs:string" default="" minOccurs="0"/>
<xs:element name="PatientNotes" type="xs:string" default="" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="MeasureRec">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" default="">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="11"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="RecID" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="MAM" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="Arrhythmia" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="ReadingDate" type="xs:dateTime" minOccurs="0"/>
<xs:element name="Sys" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="Dia" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="Map" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="PP" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="Pulse" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="Error" type="xs:int" default="0" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Comment">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" default="">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="11"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CommentID" type="xs:int"/>
<xs:element name="Degree" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="BeginDate" type="xs:dateTime" minOccurs="0"/>
<xs:element name="EndDate" type="xs:dateTime" minOccurs="0"/>
<xs:element name="Comment" type="xs:string" default="AAA" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DataTransferLog">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" default="">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="11"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="RecID" type="xs:int" default="0" minOccurs="0"/>
<xs:element name="TransferDate" type="xs:dateTime" minOccurs="0"/>
<xs:element name="NumofRecord" type="xs:int" default="0" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Patient"/>
<xs:field xpath="ID"/>
</xs:unique>
<xs:unique name="MeasureRec_Constraint1" msdata:ConstraintName="Constraint1">
<xs:selector xpath=".//MeasureRec"/>
<xs:field xpath="RecID"/>
</xs:unique>
<xs:unique name="Comment_Constraint1" msdata:ConstraintName="Constraint1">
<xs:selector xpath=".//Comment"/>
<xs:field xpath="CommentID"/>
</xs:unique>
<xs:unique name="Constraint2" msdata:PrimaryKey="true">
<xs:selector xpath=".//Comment"/>
<xs:field xpath="ID"/>
<xs:field xpath="CommentID"/>
</xs:unique>
<xs:unique name="DataTransferLog_Constraint1" msdata:ConstraintName="Constraint1">
<xs:selector xpath=".//DataTransferLog"/>
<xs:field xpath="RecID"/>
</xs:unique>
</xs:element>
</xs:schema>
<Patient>
<ID>A1234567890</ID>
<FamilyName>Sample</FamilyName>
<GivenNames>Patient</GivenNames>
<Address>Max Schmidhelny Strasse 201 9435 Heerbrugg, Switzerland.</Address>
<PhoneEmail>+41-71-727-7030/admin@microlife.ch</PhoneEmail>
<DateOfBirth>1937-05-06T18:00:00+02:00</DateOfBirth>
<Weight>94.34733</Weight>
<Height>177.8</Height>
<Sex>1</Sex>
<Smoker>0</Smoker>
<Diabetic>0</Diabetic>
<Cholestrol>190</Cholestrol>
<FamilyHistory>Not available.</FamilyHistory>
<PatientNotes>This sample patient information will help you familiar with the "Blood Pressure Analyser" software by showing how new data is processed and displayed in graphical view. When adding a new patient, you can enter relevant patient details in this "Patient Notes" column</PatientNotes>
</Patient>
<MeasureRec>
<ID>A1234567890</ID>
<RecID>1000000</RecID>
<MAM>0</MAM>
<Arrhythmia>0</Arrhythmia>
<ReadingDate>2009-03-21T12:16:00+01:00</ReadingDate>
<Sys>143</Sys>
<Dia>92</Dia>
<Map>109</Map>
<PP>51</PP>
<Pulse>82</Pulse>
<Error>0</Error>
</MeasureRec>
<MeasureRec>
<ID>A1234567890</ID>
<RecID>1000001</RecID>
<MAM>0</MAM>
<Arrhythmia>0</Arrhythmia>
<ReadingDate>2009-03-22T04:21:00+01:00</ReadingDate>
<Sys>136</Sys>
<Dia>88</Dia>
<Map>104</Map>
<PP>48</PP>
<Pulse>72</Pulse>
<Error>0</Error>
</MeasureRec>
<MeasureRec>
<ID>A1234567890</ID>
<RecID>1000002</RecID>
<MAM>1</MAM>
<Arrhythmia>0</Arrhythmia>
<ReadingDate>2009-03-22T10:58:00+01:00</ReadingDate>
<Sys>140</Sys>
<Dia>95</Dia>
<Map>110</Map>
<PP>45</PP>
<Pulse>75</Pulse>
<Error>0</Error>
</MeasureRec>
<MeasureRec>
<ID>A1234567890</ID>
<RecID>1000003</RecID>
<MAM>0</MAM>
<Arrhythmia>0</Arrhythmia>
<ReadingDate>2009-03-23T02:25:00+01:00</ReadingDate>
<Sys>133</Sys>
<Dia>80</Dia>
<Map>97</Map>
<PP>53</PP>
<Pulse>86</Pulse>
<Error>0</Error>
</MeasureRec>
<Comment>
<ID>A1234567890</ID>
<CommentID>10000</CommentID>
<Degree>3</Degree>
<BeginDate>2009-04-02T02:11:47.933+02:00</BeginDate>
<EndDate>2009-04-04T00:41:57.412+02:00</EndDate>
<Comment>3 hours in health club
</Comment>
</Comment>
<Comment>
<ID>A1234567890</ID>
<CommentID>10001</CommentID>
<Degree>2</Degree>
<BeginDate>2009-04-06T23:33:27.303+02:00</BeginDate>
<EndDate>2009-04-09T00:44:14.658+02:00</EndDate>
<Comment>fatty food
party everyday</Comment>
</Comment>
<Comment>
<ID>A1234567890</ID>
<CommentID>10002</CommentID>
<Degree>3</Degree>
<BeginDate>2009-04-10T20:40:23.755+02:00</BeginDate>
<EndDate>2009-04-17T13:16:50.703+02:00</EndDate>
<Comment>travelling
irregular medication</Comment>
</Comment>
<Comment>
<ID>A1234567890</ID>
<CommentID>10003</CommentID>
<Degree>2</Degree>
<BeginDate>2009-04-04T18:57:22.877+02:00</BeginDate>
<EndDate>2009-04-05T01:22:48.011+02:00</EndDate>
<Comment>business lunch
400 c.c. alcohol
return visit
in the afternoon</Comment>
</Comment>
<DataTransferLog>
<ID>A1234567890</ID>
<RecID>100002</RecID>
<TransferDate>2009-03-27T10:19:03.0257856+01:00</TransferDate>
<NumofRecord>3</NumofRecord>
</DataTransferLog>
<DataTransferLog>
<ID>A1234567890</ID>
<RecID>100003</RecID>
<TransferDate>2009-04-05T11:19:03.0257856+02:00</TransferDate>
<NumofRecord>3</NumofRecord>
</DataTransferLog>
<DataTransferLog>
<ID>A1234567890</ID>
<RecID>100004</RecID>
<TransferDate>2009-04-11T11:19:03.0257856+02:00</TransferDate>
<NumofRecord>3</NumofRecord>
</DataTransferLog>
<DataTransferLog>
<ID>A1234567890</ID>
<RecID>100005</RecID>
<TransferDate>2009-04-18T11:19:03.0257856+02:00</TransferDate>
<NumofRecord>3</NumofRecord>
</DataTransferLog>
<DataTransferLog>
<ID>A1234567890</ID>
<RecID>100006</RecID>
<TransferDate>2009-04-25T11:19:03.0257856+02:00</TransferDate>
<NumofRecord>3</NumofRecord>
</DataTransferLog>
</NewDataSet>
我只能在没有xsd:schema部分的情况下处理此问题。如何序列化/反序列化完整的xml文件?
我能够从您的样本文件中加载NewDataSet和相应的Patient/Measurements等使用此代码段。
void Main()
{
var path = @"... path to your sample xml";
// you could skip this step, and deserialize directly from a file stream.
var xml = XElement.Load(path);
var nds = new XmlSerializer(typeof(NewDataSet)).Deserialize(xml.CreateReader());
nds.Dump();
}
public class NewDataSet
{
public Patient Patient { get; set; }
[XmlElement("MeasureRec")]
public MeasureRec[] Recs { get; set; }
[XmlElement("Comment")]
public Comment[] Comment { get; set; }
}
public class MeasureRec
{
public int Pulse { get; set; }
}
public class Comment
{
[XmlElement("Comment")]
public string Text { get; set; }
}
public class Patient
{
public string FamilyName { get; set; }
public string GivenNames { get; set; }
}
给出一个NewDataSet
实例,其族名称和给定名称填充在Patient
、MeasureRec
和一些Comment
中。
根据Jim的回答和评论,我认识到我在反序列化时的问题是xsd2code为每个元素生成一个Order
XmlElementAttribute。如果我删除了这些属性,那么反序列化就可以很好地处理这个xml。如果我从xml中删除schema
元素,它也可以工作(不更改生成的代码中的任何内容)。不幸的是,我不能通过为BP Analyzer编写xml来省略这个元素,因为只有当存在这个元素时,它才能导入xml文件。因此,我的最终解决方案是保留xsd2code生成的原始代码(来自给定的模式),并添加以下分部类,该类在读取时删除并记住schema
元素,并在写入时将其插入回。
partial class NewDataSet
{
[XmlIgnore]
public XNode schema { get; set; }
public static NewDataSet Read(string path)
{
var xml = XElement.Load(path);
var schema = xml.FirstNode;
xml.FirstNode.Remove();
string xmlstring = xml.ToString();
var ret = NewDataSet.Deserialize(xmlstring);
ret.schema = schema;
return ret;
}
public void Write(string path)
{
var XmlString = this.Serialize();
var xml = XElement.Parse(XmlString);
xml.AddFirst(this.schema);
xml.Save(path);
}
}
Serialize和Deserialize方法由xsd2code编写。