【问题标题】:Serialize XML with Namespace使用命名空间序列化 XML
【发布时间】:2018-12-22 07:21:42
【问题描述】:

我想生成以下 XML 请求。当我使用 XML 到 C# 工具为此请求生成类然后序列化以调用 web 服务时,我生成的请求在根目录中没有 p:,因此我的请求失败。有人可以帮忙吗?

<?xml version="1.0" encoding="utf-8"?>
<p:DCTRequest xmlns:p="http://www.dhl.com" xmlns:p1="http://www.dhl.com/datatypes" xmlns:p2="http://www.dhl.com/DCTRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dhl.com DCT-req.xsd ">
  <GetQuote>
    <Request>
      <ServiceHeader>
        <MessageTime>2002-08-20T11:28:56.000-08:00</MessageTime>
        <MessageReference>1234567890123456789012345678901</MessageReference>
        <SiteID>DDDDD</SiteID>
        <Password>XXXX</Password>
      </ServiceHeader>
    </Request>
  </GetQuote>
</p:DCTRequest>

这是我序列化类的代码:

public static string Serialize(object dataToSerialize) 
{ 
    if (dataToSerialize == null) return null; 
    using (Utf8StringWriter stringwriter = new Utf8StringWriter()) 
    { 
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();  
        ns.Add("p", "DCTRequest"); 
        var serializer = new XmlSerializer(dataToSerialize.GetType()); 
        serializer.Serialize(stringwriter, dataToSerialize); 
        return stringwriter.ToString(); 
    } 
}

【问题讨论】:

  • 展示如何进行序列化。
  • public static string Serialize(object dataToSerialize) { if (dataToSerialize == null) return null; using (Utf8StringWriter stringwriter = new Utf8StringWriter()) { //XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); // ns.Add("p", "DCTRequest"); var serializer = new XmlSerializer(dataToSerialize.GetType()); serializer.Serialize(stringwriter, dataToSerialize);返回 stringwriter.ToString(); } } //我用这个函数进行序列化
  • Edit 问题。移动注释中的代码。

标签: c# xml serialization


【解决方案1】:

这是实现预期结果的一种方法。我使用以下类结构进行了测试。除了在 DCTRequest 上具有 SchemaLocation 属性以确保您在最终 XML 中获得 xsi:schemaLocation 并将外部命名空间设置为“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 的简写方式。
  • 您没有在对serializer.Serialize 的调用中传递XmlSerializerNamespaces 的实例,所以它没有被使用,也没有做任何事情。

这是一个固定版本:

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    • 2013-05-02
    相关资源
    最近更新 更多