如何在C#生成的XML中为Envelope添加s:前缀?
解决C#中XElement生成带命名空间前缀的SOAP Envelope问题
需求目标
需要生成如下XML结构:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> </s:Envelope>
之前的错误尝试及问题
第一次尝试代码
XNamespace myns = "s"; XDocument oXml = new XDocument(new XDeclaration("1.0", "UTF-8", "")); XElement oRoot = new XElement("Envelope", new XAttribute(XNamespace.Xmlns + "s", "http://schemas.xmlsoap.org/soap/envelope/"), new XAttribute(XNamespace.Xmlns + "a", "http://www.w3.org/2005/08/addressing"), new XAttribute(XNamespace.Xmlns + "fse", "http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/"), new XAttribute(XNamespace.Xmlns + "u", "http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") ); oXml.Add(oRoot);
生成结果缺少s:前缀:
<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" />
第二次尝试代码
XNamespace myns = "s"; XElement oRoot = new XElement(myns + "Envelope", new XAttribute(XNamespace.Xmlns + "s", "http://schemas.xmlsoap.org/soap/envelope/"), new XAttribute(XNamespace.Xmlns + "a", "http://www.w3.org/2005/08/addressing"), new XAttribute(XNamespace.Xmlns + "fse", "http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/"), new XAttribute(XNamespace.Xmlns + "u", "http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") );
生成结果多出了xmlns="s"属性:
<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="s" />
错误原因
核心问题是XNamespace的赋值错误:你把XNamespace myns设成了前缀s,但实际上XNamespace需要绑定的是命名空间的URI,而不是前缀。前缀s是通过Xmlns属性来关联到对应URI的。
正确解决方案
修正XNamespace的定义,将其设置为SOAP信封的命名空间URI,然后创建XElement时使用该命名空间+元素名,同时保留原有的Xmlns属性定义:
// 正确定义命名空间为SOAP信封的URI XNamespace sNs = "http://schemas.xmlsoap.org/soap/envelope/"; XDocument oXml = new XDocument(new XDeclaration("1.0", "UTF-8", "")); XElement oRoot = new XElement(sNs + "Envelope", // 绑定前缀s到对应的命名空间URI new XAttribute(XNamespace.Xmlns + "s", sNs), new XAttribute(XNamespace.Xmlns + "a", "http://www.w3.org/2005/08/addressing"), new XAttribute(XNamespace.Xmlns + "fse", "http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/"), new XAttribute(XNamespace.Xmlns + "u", "http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") ); oXml.Add(oRoot);
生成的正确结果
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" />
内容的提问来源于stack exchange,提问作者Modest
相关产品推荐
相关产品推荐

