C#XmlSerializer在子节点中使用前缀定义名称空间

问题描述

我需要使用C#创建一个XML文档,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Container>
  <Info>
    <request xmlns:a="http://www.UKMail.com/Services/Contracts/DataContracts">
      <a:AuthenticationToken>token</a:AuthenticationToken>
      <a:Username>username</a:Username>
      <a:ConsignmentNumber>12345</a:ConsignmentNumber>
    </request>
  </Info>
</Container>

关键部分是在子节点而不是根节点中带有前缀(xmlns:a = ...)的名称空间定义。到目前为止,我只能制作此文档:

<?xml version="1.0" encoding="utf-8"?>
<Container xmlns:a="http://www.UKMail.com/Services/Contracts/DataContracts">
  <Info>
    <a:request>
      <a:AuthenticationToken>token</a:AuthenticationToken>
      <a:Username>username</a:Username>
      <a:ConsignmentNumber>12345</a:ConsignmentNumber>
    </a:request>
  </Info>
</Container>

这被Web服务拒绝-如果将xmlns:a ..部分移动到请求节点,Web服务对此会感到满意。

这是我目前生成XML的方式:

class Program
    {
        static void Main(string[] args)
        {
            SerializeObject("XmlNamespaces.xml");
        }

        public static void SerializeObject(string filename)
        {
            var mySerializer = new XmlSerializer(typeof(Container));
            // Writing a file requires a TextWriter.
            TextWriter myWriter = new StreamWriter(filename);

            // Creates an XmlSerializerNamespaces and adds two
            // prefix-namespace pairs.
            var myNamespaces = new XmlSerializerNamespaces();
            myNamespaces.Add("a","http://www.UKMail.com/Services/Contracts/DataContracts");


            Container container = new Container
            {
                Info = new CancelConsignmentRequest
                {
                    request = new CancelConsignmentRequestInfo
                    {
                        AuthenticationToken = "token",ConsignmentNumber = "12345",Username = "username"
                    }
                }
            };

            mySerializer.Serialize(myWriter,container,myNamespaces);
            myWriter.Close();
        }
    }

    public class Container
    {
        public CancelConsignmentRequest Info { get; set; } = new CancelConsignmentRequest();
    }

    [XmlRoot(Namespace = "http://www.UKMail.com/Services/Contracts/ServiceContracts")]
    public class CancelConsignmentRequest
    {
        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts")]
        public CancelConsignmentRequestInfo request { get; set; } = new CancelConsignmentRequestInfo();
    }

    public class CancelConsignmentRequestInfo
    {
        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts",Order = 0)]
        public string AuthenticationToken { get; set; }
        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts",Order = 1)]
        public string Username { get; set; }

        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts",Order = 2)]
        public string ConsignmentNumber { get; set; }
    }

我无法弄清楚如何在子节点之一中放置带有前缀的名称空间定义。有人知道如何在C#中执行此操作吗?谢谢。

解决方法

这是可能的。下面的代码可以满足您的要求。

class Program
{
    static void Main(string[] args)
    {
        SerializeObject("XmlNamespaces.xml");
    }

    public static void SerializeObject(string filename)
    {
        var mySerializer = new XmlSerializer(typeof(Container));
        // Writing a file requires a TextWriter.
        TextWriter myWriter = new StreamWriter(filename);

        // Creates an XmlSerializerNamespaces and adds two
        // prefix-namespace pairs.
        var myNamespaces = new XmlSerializerNamespaces();
        //myNamespaces.Add("a","http://www.UKMail.com/Services/Contracts/DataContracts");

        Container container = new Container
        {
            Info = new CancelConsignmentRequest
            {
                request = new CancelConsignmentRequestInfo
                {
                    AuthenticationToken = "token",ConsignmentNumber = "12345",Username = "username"
                }
            }
        };

        mySerializer.Serialize(myWriter,container,myNamespaces);
        myWriter.Close();
    }
}

public class Container
{
    public CancelConsignmentRequest Info { get; set; } = new CancelConsignmentRequest();
}

public class CancelConsignmentRequest
{
    public CancelConsignmentRequestInfo request { get; set; } = new CancelConsignmentRequestInfo();
}

[XmlRoot(Namespace = "http://www.UKMail.com/Services/Contracts/ServiceContracts")]
public class CancelConsignmentRequestInfo
{
    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(
        new[] { new XmlQualifiedName("a","http://www.UKMail.com/Services/Contracts/DataContracts"),});
    [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts",Order = 0)]
    public string AuthenticationToken { get; set; }
    [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts",Order = 1)]
    public string Username { get; set; }

    [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts",Order = 2)]
    public string ConsignmentNumber { get; set; }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...