首页 文章

如何在C#中使用XML序列化包含元素(而不是根)的属性

提问于
浏览
4

我需要生成一个如下所示的XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<inboundMessage xmlns="http://www.myurl.net">
  <header>
    <password>mypwd</password>
    <subscriberId>myuser</subscriberId>
  </header>
  <message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="myType">
    <eventDate>2012-09-05T12:13:45.561-05:00</eventDate>
    <externalEventId />
    <externalId>SomeIdC</externalId>
  </message>
</inboundMessage>

问题是我不知道如何在我的标签中包含xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”xsi:type =“myType” . 我需要序列化的类是这样的:

[XmlType("inboundMessage")]
[XmlRoot(Namespace = "http://www.myurl.net")]
public class InboundMessage
{
    [XmlElement(ElementName = "header")]
    public Header _header;
    [XmlElement(ElementName = "message")]
    public List<MyType> _messages;
}

我需要将哪些XmlAttributes添加到我的“_messages”成员中,以便按照我想要的方式进行序列化?

TIA,Ed

2 回答

  • 1

    像这样使用 XmlAttribute

    public class MyType
    {
        [XmlAttribute("type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public string Type { get; set; }
    }
    
  • 0

    我的一个coleague提出了一个类似的解决方案,但更完整 . MyType添加了两个属性:

    [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces Namespaces { get; set; }
    
        [XmlAttribute("type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }
    

    _type的定义如下:

    private string _type = "myType";
    

    然后序列化以不同的方式完成:

    // declare an XmlAttributes object, indicating that the namespaces declaration should be kept
            var atts = new XmlAttributes { Xmlns = true };
    
            // declare an XmlAttributesOverrides object and ...
            var xover = new XmlAttributeOverrides();
            // ... add the XmlAttributes object with regard to the "Namespaces" property member of the "Message" type
            xover.Add(typeof(MyType), "Namespaces", atts);
    
            // set the Namespaces property for each message in the payload body
            var messageNamespaces = new XmlSerializerNamespaces();
            messageNamespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            foreach (var message in myInboundMessage._messages)
            {
                message.Namespaces = messageNamespaces;
            }
    
            // create a serializer
            var serializer = new XmlSerializer(object2Serialize.GetType(), xover);
    
            // add the namespaces for the root element
            var rootNamespaces = new XmlSerializerNamespaces();
            rootNamespaces.Add("", "http://www.myurl.net");
    
            // serialize and extract the XML as text
            string objectAsXmlText;
            using (var stream = new MemoryStream())
            using (var xmlTextWriter = new XmlTextWriter(stream, null))
            {
                serializer.Serialize(xmlTextWriter, object2Serialize, rootNamespaces);
                stream.Seek(0, SeekOrigin.Begin);
                var buffer = new byte[stream.Length];
                stream.Read(buffer, 0, (int)stream.Length);
                objectAsXmlText = Encoding.UTF8.GetString(buffer);
            }
    

    最后,InboundMessage的装饰如下:

    [XmlRoot("inboundMessage", Namespace = "http://www.myurl.net")]
    

    通过这种方法,我得到了我需要的东西 .

相关问题