我有一个对象需要序列化为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字符串。
提前致谢。
答案 0 :(得分: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属性,你永远不能完全删除它,但是类似下面的代码可以帮助你确保它只在顶层发出一次:
注意突出显示的命名空间是如何定义五次的,当它只能在顶层定义一次时会产生很多膨胀。要解决此问题,您可以使用以下代码:
ser.WriteStartObject(writer, o);
writer.WriteAttributeString("xmlns", "p", null, "some-reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally-long-namespace.com/");
ser.WriteObjectContent(writer, o);
ser.WriteEndObject(writer);