Program.cs
.net 8.0已經內建了XML解析器,所以直接在services.AddControllers()
後呼叫AddXmlSerializerFormatters()
即可:
services.AddControllers().AddXmlSerializerFormatters();
定義實體
需要用到幾個特性:
- XmlRoot:xml的根節點
- XmlElement:xml的成員
例:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:i="http://i.api.ei.nxyincfuyou.iih/">
<soapenv:Header/>
<soapenv:Body>
<i:apiEntry>
<i:arg0>SI0084</i:arg0>
<i:arg1>
<![CDATA[
<iihparam>
<Code_user>00000</Code_user>
<Code_dep></Code_dep>
<Code_external>IIH</Code_external>
<Data>
<Code_dep></Code_dep>
<Code_nur>00034</Code_nur>
<Sd_status>25</Sd_status>
<Date_b_in></Date_b_in>
<Date_e_in></Date_e_in>
<Date_b_out></Date_b_out>
<Date_e_out></Date_e_out>
<Date_b_update></Date_b_update>
<Date_e_update></Date_e_update>
<Pageinfos>
<Pageinfo>
<Pagesize>200</Pagesize>
<Pageindex>1</Pageindex>
<Pagecount></Pagecount>
<Recordscount></Recordscount>
</Pageinfo>
</Pageinfos>
</Data>
</iihparam>
]]>
</i:arg1>
</i:apiEntry>
</soapenv:Body>
</soapenv:Envelope>
// 根元素
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class H5_InpatientDataXML
{
[XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
}
public class Header
{
// 你可以新增更多的頭資訊屬性,如果需要的話
}
public class Body
{
[XmlElement(ElementName = "apiEntry", Namespace = "http://i.api.ei.nxyincfuyou.iih/")]
public ApiEntry ApiEntry { get; set; }
}
public class ApiEntry
{
[XmlElement(ElementName = "arg0", Namespace = "http://i.api.ei.nxyincfuyou.iih/")]
public string Arg0 { get; set; }
[XmlElement(ElementName = "arg1", Namespace = "http://i.api.ei.nxyincfuyou.iih/")]
public CData<IihParam> Arg1 { get; set; }
}
// Arg1中的巢狀 XML
[XmlRoot(ElementName = "iihparam")]
public class IihParam
{
[XmlElement(ElementName = "Code_user")]
public string CodeUser { get; set; }
[XmlElement(ElementName = "Code_dep")]
public string CodeDep { get; set; }
[XmlElement(ElementName = "Code_external")]
public string CodeExternal { get; set; }
[XmlElement(ElementName = "Data")]
public Data Data { get; set; }
}
public class Data
{
[XmlElement(ElementName = "Code_dep")]
public string CodeDep { get; set; }
[XmlElement(ElementName = "Code_nur")]
public string CodeNur { get; set; }
[XmlElement(ElementName = "Sd_status")]
public string SdStatus { get; set; }
[XmlElement(ElementName = "Date_b_in")]
public string DateBIn { get; set; }
[XmlElement(ElementName = "Date_e_in")]
public string DateEIn { get; set; }
[XmlElement(ElementName = "Date_b_out")]
public string DateBOut { get; set; }
[XmlElement(ElementName = "Date_e_out")]
public string DateEOut { get; set; }
[XmlElement(ElementName = "Date_b_update")]
public string DateBUpdate { get; set; }
[XmlElement(ElementName = "Date_e_update")]
public string DateEUpdate { get; set; }
[XmlElement(ElementName = "Pageinfos")]
public PageInfos PageInfos { get; set; }
}
public class PageInfos
{
[XmlElement(ElementName = "Pageinfo")]
public List<PageInfo> PageInfoList { get; set; }
}
public class PageInfo
{
[XmlElement(ElementName = "Pagesize")]
public string PageSize { get; set; }
[XmlElement(ElementName = "Pageindex")]
public string PageIndex { get; set; }
[XmlElement(ElementName = "Pagecount")]
public string PageCount { get; set; }
[XmlElement(ElementName = "Recordscount")]
public string RecordsCount { get; set; }
}
這裡注意,CDATA區域需要自定義序列化方式以便框架呼叫,CDATA類:
public class CData<T> : IXmlSerializable where T : class
{
public T Value { get; set; }
public XmlSchema GetSchema() => null;
public void ReadXml(XmlReader reader)
{
if (reader.IsEmptyElement)
{
reader.Read();
Value = null;
}
else
{
string content = reader.ReadElementContentAsString();
if (!string.IsNullOrEmpty(content))
{
var serializer = new XmlSerializer(typeof(T));
using (var stringReader = new StringReader(content))
{
Value = (T)serializer.Deserialize(stringReader);
}
}
}
}
public void WriteXml(XmlWriter writer)
{
if (Value != null)
{
var serializer = new XmlSerializer(typeof(T));
using (var stringWriter = new StringWriter())
{
serializer.Serialize(stringWriter, Value);
writer.WriteCData(stringWriter.ToString());
}
}
}
public static implicit operator CData<T>(T value)
{
return new CData<T> { Value = value };
}
public static implicit operator T(CData<T> cdata)
{
return cdata?.Value;
}
}
另外注意資料型別一般都是string,之前對於PageCount使用了int,測試時發現會報錯。
Controller使用
/// <summary>
/// 獲取患者的xml格式資料
/// </summary>
/// <param name="xmlData"></param>
/// <returns></returns>
[HttpPost]
[Route("TestXML")]
public async Task<IActionResult> TestXML([FromBody] H5_InpatientDataXML envelope)
{
return Ok(envelope);
}