0

XML にシリアル化したいオブジェクトがあり、次のコードを使用してこれを実行しています。

 public static string Serialize(object obj)
    {
        using (var memoryStream = new MemoryStream())
        using (var reader = new StreamReader(memoryStream))
        {
            var serializer = new DataContractSerializer(obj.GetType());
            serializer.WriteObject(memoryStream, obj);
            memoryStream.Position = 0;
            return reader.ReadToEnd();
        }
    }

すると、次の XML が得られます。

<TestRequestPOCO xmlns=\"http://schemas.datacontract.org/2004/07/GPTR.Model.POCOs\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">
    <AdditionalInformation>Additional Information</AdditionalInformation>
    <AddressLine1>6 MOUNT PLEASANT ROAD</AddressLine1>
    <AddressLine2>LEEDS</AddressLine2>
    <AddressLine3 i:nil=\"true\"/>
    <AddressLine4 i:nil=\"true\"/>
    <AntibioticTherapy i:nil=\"true\"/>
    <ClinicalInformation>Clinical Information</ClinicalInformation>
    <ClinicalInformationXml i:nil=\"true\"/>
    <Clinician>Dr NM BRYAN</Clinician>
    <ClinicianCode>4203845</ClinicianCode>
    <ClinicianShortCode :nil=\"true\"/>
    <Destination>1</Destination>
    <Dob>1992-02-29T00:00:00</Dob>
    <ExpectedDate>2011-10-06T10:22:57.096+01:00</ExpectedDate>
    <FirstName>ALISON</FirstName>
    <GenerateOrder>true</GenerateOrder>
    <HospitalNumber i:nil=\"true\"/>
    <IsFasting>false</IsFasting>
    <IsPrivatePatient>false</IsPrivatePatient>
    <IsSensitive>false</IsSensitive>
    <IsUrgent>false</IsUrgent>
    <Items>
        <RequestDataItem>
            <AdditionalInfo i:nil=\"true\"/>
            <Container i:nil=\"true\"/>
            <Description>Ferritin [Serum]</Description>
            <LIMSDeptName>CHM</LIMSDeptName>
            <ProfileNumber>1293</ProfileNumber>
            <QualifierCode i:nil=\"true\"/>
            <SiteCode i:nil=\"true\"/>
            <SpecimenType>Serum</SpecimenType>
            <UniqueTest>False</UniqueTest>
        </RequestDataItem>
    </Items>
    <Location>0</Location>
    <LocationName>The INPS Practice</LocationName>
    <LocationShortCode>W97046</LocationShortCode>
    <LocationTelephone>01792602898</LocationTelephone>
    <MiddleName i:nil=\"true\"/>
    <NhsNumber>5240022631</NhsNumber>
    <OrgCode>RRS</OrgCode>
    <Placer>Dr Sarah Saturn</Placer>
    <PostCode>CF31 5EP</PostCode>
    <Sex>Male</Sex>
    <Source>GPTR</Source>
    <SurName>WILLIAMS</SurName>
    <TelephoneNumber>01792776776</TelephoneNumber>
</TestRequestPOCO>"

ご覧のとおり、空のタグをうまく処理できません。また、ルート タグのテキストを削除したいので、次のようになります。

<TestRequestPOCO>
    <AdditionalInformation>Additional Information</AdditionalInformation>
    <AddressLine1>6 MOUNT PLEASANT ROAD</AddressLine1>
    <AddressLine2>LEEDS</AddressLine2>
    <AddressLine3/>
    <AddressLine4/>
    <AntibioticTherapy>
    <ClinicalInformation>Clinical Information</ClinicalInformation>
    <ClinicalInformationXml/>
    <Clinician>Dr NM BRYAN</Clinician>
    <ClinicianCode>4203845</ClinicianCode>
    <ClinicianShortCode/>
    <Destination>1</Destination>
    <Dob>1992-02-29T00:00:00</Dob>
    <ExpectedDate>2011-10-06T10:22:57.096+01:00</ExpectedDate>
    <FirstName>ALISON</FirstName>
    <GenerateOrder>true</GenerateOrder>
    <HospitalNumber/>
    <IsFasting>false</IsFasting>
    <IsPrivatePatient>false</IsPrivatePatient>
    <IsSensitive>false</IsSensitive>
    <IsUrgent>false</IsUrgent>
    <Items>
        <RequestDataItem>
            <AdditionalInfo/>
            <Container/>
            <Description>Ferritin [Serum]</Description>
            <LIMSDeptName>CHM</LIMSDeptName>
            <ProfileNumber>1293</ProfileNumber>
            <QualifierCode/>
            <SiteCode/>
            <SpecimenType>Serum</SpecimenType>
            <UniqueTest>False</UniqueTest>
        </RequestDataItem>
    </Items>
    <Location>0</Location>
    <LocationName>The INPS Practice</LocationName>
    <LocationShortCode>W97046</LocationShortCode>
    <LocationTelephone>01792602898</LocationTelephone>
    <MiddleName />
    <NhsNumber>5240022631</NhsNumber>
    <OrgCode>RRS</OrgCode>
    <Placer>Dr Sarah Saturn</Placer>
    <PostCode>CF31 5EP</PostCode>
    <Sex>Male</Sex>
    <Source>GPTR</Source>
    <SurName>WILLIAMS</SurName>
    <TelephoneNumber>01792776776</TelephoneNumber>
</TestRequestPOCO>"

これらを取り除き、上記のような XML の文字列を作成する方法を知っている人はいますか?

前もって感謝します。

4

1 に答える 1

2

「null」値 (i:nil が true に設定されている値) を削除するには、これらのデータ メンバーの DataMemberAttribute の「EmitDefaultValue」を false に設定する必要があります。.NET Framework では、型には既定値の概念があります。たとえば、参照型のデフォルト値は null で、整数型の場合は 0 です。

次に例を示します。

[DataContract]
public class Employee
{
    // The CLR default for as string is a null value.
    // This will be written as <employeeName xsi:nill="true" />
    [DataMember]
    public string EmployeeName = null;

    // This will be written as <employeeID>0</employeeID>
    [DataMember]
    public int employeeID = 0;

    // The next three will not be written because the EmitDefaultValue = false.
    [DataMember(EmitDefaultValue = false)]
    public string position = null;
    [DataMember(EmitDefaultValue = false)]
    public int salary = 0;
    [DataMember(EmitDefaultValue = false)]
    public int? bonus = null;

    // This will be written as <targetSalary>57800</targetSalary> 
    [DataMember(EmitDefaultValue = false)]
    public int targetSalary = 57800;
}

これを行う前に、よく考えていただきたいと思います。その理由は、EmitDefaultValue が false に設定されている場合、Windows Communication Foundation (WCF) に固有の注釈としてスキーマで表されるためです。この情報を表す相互運用可能な方法はありません。特に、スキーマの "default" 属性はこの目的には使用されず、minOccurs 属性は IsRequired 設定によってのみ影響を受け、nillable 属性はデータ メンバーの型によってのみ影響を受けます。

他のさまざまな不要な XML 属性の削除に関しては、完全に削除することはできませんが、次のコードのようなものを使用すると、トップ レベルで 1 回だけ出力されるようにすることができます。

強調表示された名前空間が 5 回定義されていることに注意してください。最上位で 1 回しか定義できなかったのに、多くの肥大化が生じています。この問題を解決するには、次のコードを使用できます。

ser.WriteStartObject(writer, o);    
writer.WriteAttributeString("xmlns", "p", null, "some-reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally-long-namespace.com/");    
ser.WriteObjectContent(writer, o);    
ser.WriteEndObject(writer);
于 2012-04-27T14:13:45.153 に答える