在.NET Core(C#)中如何重复添加含不同内容的相同XML标签
问题描述
我在.NET Core中基于WebService的.wsdl文件创建API,目前用硬编码拼接XML的方式生成SOAP请求体,代码如下:
XDocument xDocument = XDocument.Parse( "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'><soapenv:Header/> <soapenv:Body> <MyServiceRequest> <ITEMSLIST> <ITEMS> <ID>" + request.ID + "</ID> <NAME>" + request.NAME + "</NAME> </ITEMS> </ITEMSLIST> </acc:MyServiceRequest> </soapenv:Body> </soapenv:Envelope>"); var xmlRequestBody = xDocument.ToString();
值来自以下模型数组:
Items[] request public class Items { public string ID { get; set; } public string NAME { get; set; } }
单个Items对象时生成的XML正常,但多个对象时无法生成预期格式。当前生成的XML只有一个<ITEMS>节点,而目标XML需要在<ITEMSLIST>下生成多个<ITEMS>节点,格式如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <acc:MyServiceRequest> <ITEMSLIST> <ITEMS> <ID>06285883</ID> <NAME>John</NAME> </ITEMS> <ITEMS> <ID>06285231</ID> <NAME>Sara</NAME> </ITEMS> </ITEMSLIST> </acc:MyServiceRequest> </soapenv:Body> </soapenv:Envelope>
请问如何动态添加多个<ITEMS>节点到XML中?
解决方案
方法1:使用LINQ to XML构建(推荐)
这种方式比字符串拼接更安全,能自动处理XML命名空间和节点结构,避免拼接错误:
// 定义命名空间 XNamespace soapenv = "http://schemas.xmlsoap.org/soap/envelope/"; XNamespace acc = "这里替换成acc命名空间的实际URL"; // 注意原XML里的<acc:MyServiceRequest>需要对应的命名空间 // 构建XML结构 var envelope = new XElement(soapenv + "Envelope", new XAttribute(XNamespace.Xmlns + "soapenv", soapenv), new XAttribute(XNamespace.Xmlns + "acc", acc), new XElement(soapenv + "Header"), new XElement(soapenv + "Body", new XElement(acc + "MyServiceRequest", new XElement("ITEMSLIST", // 遍历Items数组生成每个ITEMS节点 from item in request select new XElement("ITEMS", new XElement("ID", item.ID), new XElement("NAME", item.NAME) ) ) ) ) ); var xmlRequestBody = envelope.ToString();
注意:需要替换代码中acc命名空间的实际URL,原XML里的<acc:MyServiceRequest>对应了一个命名空间,可从.wsdl文件或原请求XML中找到该URL。
方法2:修正字符串拼接方式
如果一定要用字符串拼接,需要遍历Items数组生成所有<ITEMS>节点的字符串,再插入到XML模板中:
// 生成所有ITEMS节点的字符串 var itemsXml = string.Join("", request.Select(item => $@" <ITEMS> <ID>{item.ID}</ID> <NAME>{item.NAME}</NAME> </ITEMS>")); // 构建完整XML模板,插入生成的itemsXml var xmlTemplate = $@"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:acc='这里替换成acc命名空间的实际URL'> <soapenv:Header/> <soapenv:Body> <acc:MyServiceRequest> <ITEMSLIST> {itemsXml} </ITEMSLIST> </acc:MyServiceRequest> </soapenv:Body> </soapenv:Envelope>"; XDocument xDocument = XDocument.Parse(xmlTemplate); var xmlRequestBody = xDocument.ToString();
这种方式需要注意XML转义问题,如果ID或NAME包含特殊字符(比如<、&),会导致XML格式错误,因此更推荐方法1。
内容的提问来源于stack exchange,提问作者Ali Mumtaz
相关产品推荐
相关产品推荐

