繁体   English   中英

如何在C#中反序列化/序列化Microlife的xml

[英]How to deserialize/serialize Microlife's xml in c#

当我需要处理特定的xml文件时,通常会使用xsd2code生成c#类。 但是现在,我有了Microlife的血压分析仪使用的一个奇怪的xml文件。 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 / Measurement等。

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实例,该实例具有族名,并在PatientMeasureRec和一些Comment填充给定名称。

根据Jim的回答和评论,我认识到,反序列化的问题是xsd2code为每个元素生成一个Order XmlElementAttribute。 如果我删除这些属性,则反序列化对于该xml来说工作正常。 如果我从xml中删除schema元素,它也将起作用(不更改生成的代码中的任何内容)。 不幸的是,我无法通过为BP分析器编写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编写。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM