Wenn ich eine bestimmte XML-Datei verarbeiten muss, generiere ich normalerweise c # -Klassen mit xsd2code. Aber jetzt habe ich eine seltsame XML-Datei, die von Microlifes Blutdruckmessgerät verwendet wird. Die XML-Datei enthält ihr Schema als zusätzliches erstes Element, wie in diesem Beispiel

<?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>

Ich kann dies nur ohne den xsd: schema-Teil handhaben. Wie serialisiere / deserialisiere ich die komplette XML-Datei?

0
mma 23 Dez. 2015 im 13:42

2 Antworten

Beste Antwort

Mit diesem Snippet kann ich ein NewDataSet und entsprechende Patienten / Messungen usw. aus Ihrer Beispieldatei laden.

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; }
}

Gibt eine NewDataSet Instanz mit dem Familiennamen und dem in Patient, MeasureRec und einigen Comment (s) angegebenen Vornamen an.

1
Jim 23 Dez. 2015 im 11:59

Anhand von Jims Antwort und Kommentaren erkannte ich, dass mein Problem beim Deserialisieren darin bestand, dass xsd2code für jedes Element ein Order XmlElementAttribute generiert. Wenn ich diese Attribute entferne, funktioniert die Deserialisierung für diese XML-Datei einwandfrei. Es funktioniert auch (ohne etwas im generierten Code zu ändern), wenn ich das schema -Element aus der XML entferne. Leider kann ich dieses Element nicht weglassen, indem ich eine XML für den BP Analyzer schreibe, da es die XML-Datei nur importieren kann, wenn dieses Element vorhanden ist. Meine endgültige Lösung besteht also darin, den von xsd2code (aus dem angegebenen Schema) generierten Originalcode beizubehalten und die folgende Teilklasse hinzuzufügen, die das schema -Element beim Lesen entfernt, speichert und beim Schreiben wieder einfügt.

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);
    }
}

Die Methoden Serialize und Deserialize werden von xsd2code geschrieben.

0
mma 25 Dez. 2015 im 10:36