Вот один из способов достижения желаемого результата.Я проверил, используя следующую структуру класса.Ничего особенного в этом нет, кроме наличия свойства SchemaLocation
в DCTRequest, которое гарантирует, что вы получите xsi:schemaLocation
в конечном XML, и установки внешнего пространства имен на "http://www.dhl.com", что даст ему p
префикс позже.
[XmlRoot(Namespace = "http://www.dhl.com")]
public class DCTRequest
{
[XmlAttribute(AttributeName = "schemaLocation", Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string SchemaLocation { get; set; }
[XmlElement(Namespace = "")]
public GetQuote GetQuote { get; set; }
}
public class GetQuote
{
public Request Request { get; set; }
}
public class Request
{
public ServiceHeader ServiceHeader { get; set; }
}
public class ServiceHeader
{
public DateTime MessageTime { get; set; }
public string MessageReference { get; set; }
public string SideID { get; set; }
public string Password { get; set; }
}
Я адаптировал ваш метод сериализации следующим образом: две вещи, которые вы здесь ошиблись:
- Вы передали имя объекта / элемента
DCTRequest
как пространство имен. Это неправильно, пространство имен принимает форму http://www.mynamespace.com/whatever
. В вашем случае, у вас есть xmlns:p="http://www.dhl.com"
. p
называется префиксом пространства имен. Это краткий способ ссылки на полное пространство именhttp://www.dhl.com
. - Вы не передаете экземпляр
XmlSerializerNamespaces
в вызове serializer.Serialize
, поэтому он не используется и ничего не делает.
Вот исправленная версия:
public static string Serialize(object dataToSerialize)
{
if (dataToSerialize == null) return null;
using (StringWriter stringWriter = new StringWriter())
{
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("p", "http://www.dhl.com");
namespaces.Add("p1", "http://www.dhl.com/datatypes");
namespaces.Add("p2", "http://www.dhl.com/DCTRequestdatatypes");
namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
var serializer = new XmlSerializer(dataToSerialize.GetType());
serializer.Serialize(stringWriter, dataToSerialize, namespaces);
return stringWriter.ToString();
}
}
Если вы сложите это вместе и позвоните так:
var dctRequest = new DCTRequest()
{
SchemaLocation = "http://www.dhl.com DCT-req.xsd ",
GetQuote = new GetQuote()
{
Request = new Request()
{
ServiceHeader = new ServiceHeader()
{
MessageTime = DateTime.Now,
MessageReference = "1234567890123456789012345678901",
SideID = "DDDDD",
Password = "XXXX"
}
}
}
};
var xml = Serialize(dctRequest);
Тогда вы получите желаемый XML:
<?xml version="1.0" encoding="utf-16"?>
<p:DCTRequest xmlns:p2="http://www.dhl.com/DCTRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p1="http://www.dhl.com/datatypes" xmlns:p="http://www.dhl.com" xsi:schemaLocation="http://www.dhl.com DCT-req.xsd ">
<GetQuote>
<Request>
<ServiceHeader>
<MessageTime>2018-12-22T10:09:06.6530604+00:00</MessageTime>
<MessageReference>1234567890123456789012345678901</MessageReference>
<SideID>DDDDD</SideID>
<Password>XXXX</Password>
</ServiceHeader>
</Request>
</GetQuote>
</p:DCTRequest>