首页 > 解决方案 > 当属性的命名空间为空时,如何在序列化时设置命名空间?

问题描述

我有 4 个不同的命名空间,我将它们添加如下

var namespaces = new XmlSerializerNamespaces();
namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
namespaces.Add("abc", "urn:abc");
namespaces.Add(string.Empty, "urn:efg");
namespaces.Add("xyz", "urn:xyz");

我的对象看起来像这样(小例子):

[XmlRoot(Namespace = "urn:abc")]
public class RootDocument
{
    public Header Header { get; set; }
}

public class Header
{
    //No namespace here
    public SomeNode SomeNode { get; set; }
}

public class SomeNode 
{
    [XmlElement(Namespace = "urn:xyz")]
    public OtherNode { get; set; }
}

public class OtherNode
{
    [XmlText]
    public string Value { get; set; }
}

该类SomeNode是没有命名空间的类的示例。我有 50 多个具有很多属性的类,我想避免在每个类上都设置一个命名空间。

当我序列化上述内容时,我得到:

<?xml version="1.0" encoding="utf-16"?>
<abc:RootDocument xmlns="urn:efg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xyz="urn:xyz" xmlns:abc="urn:abc">
    <abc:Header>
        <abc:SomeNode>
            <xyz:OtherNode>true</xyz:OtherNode>
        </abc:SomeNode>
    </abc:Header>
</abc:RootDocument

但是,输出必须是:

<?xml version="1.0" encoding="utf-16"?>
<abc:RootDocument xmlns:efg="urn:efg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xyz="urn:xyz" xmlns:abc="urn:abc">
    <abc:Header>
        <efg:SomeNode>
            <xyz:OtherNode>true</xyz:OtherNode>
        </efg:SomeNode>
    </abc:Header>
</abc:RootDocument

我可以在序列化期间自动将命名空间设置为efg具有空工作区的所有节点(即属性没有Namespace集合XmlElement)吗?

标签: c#xml

解决方案


如果你想在运行时更改命名空间,你有XmlAttributeOverrides

XmlAttributes 对象包含属性对象的联合,这些属性对象会导致 XmlSerializer 覆盖其对一组对象的默认序列化行为。您可以根据要覆盖的特定行为选择要放置在 XmlAttributes 对象中的属性对象。例如,默认情况下 XmlSerializer 将类成员序列化为 XML 元素。如果您希望将成员序列化为 XM 属性,您将创建一个 XmlAttributeAttribute,将其分配给 XmlAttributes 的 XmlAttribute 属性,并将 XmlAttributes 对象添加到 XmlAttributeOverrides 对象。

使用此重载覆盖 XmlRootAttribute 或 XmlTypeAttribute。

例如:

public class Group
{
   public string GroupName;
   [XmlAttribute]
   public int GroupCode;
}

  public class Sample
  {
    public XmlSerializer CreateOverrider()
    {
       // Create an XmlAttributeOverrides object. 
       XmlAttributeOverrides xOver = new XmlAttributeOverrides();

       /* Create an XmlAttributeAttribute to override the base class
       object's XmlAttributeAttribute object. Give the overriding object
       a new attribute name ("Code"). */
       XmlAttributeAttribute xAtt = new XmlAttributeAttribute();
       xAtt.AttributeName = "Code";

       /* Create an instance of the XmlAttributes class and set the 
       XmlAttribute property to the XmlAttributeAttribute object. */
       XmlAttributes attrs = new XmlAttributes();
       attrs.XmlAttribute = xAtt;

       /* Add the XmlAttributes object to the XmlAttributeOverrides
          and specify the type and member name to override. */
       xOver.Add(typeof(Group), "GroupCode", attrs);

       XmlSerializer xSer = new XmlSerializer(typeof(Group), xOver);
       return xSer;
    }
  }

还有一个,有XmlSerializerNamespaces

[XmlRoot("Node", Namespace="http://somenamepsace")]
public class MyType {
    [XmlElement("childNode")]
    public string Value { get; set; }
}

static class Program
{
    static void Main()
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("myNamespace", "http://somenamepsace");
        XmlSerializer xser = new XmlSerializer(typeof(MyType));
        xser.Serialize(Console.Out, new MyType(), ns);
    }
}

推荐阅读