默认的xml命名空间,但不是使用XmlSerializer在root上

时间:2015-04-20 17:19:50

标签: c# xml xmlserializer

所以我正在做的是使用XmlSerializer并使用自定义类。其中一个元素还需要一个默认命名空间和它自己的值。但是,默认名称空间必须是动态的。所以雅典是该位置元素的命名空间。下一个位置元素可能是伦敦。例如:

<items>
    <item>
         <location xmlns="Athens">True</location>
         <location xmlns="London">False</location>
    </item>
<items>

我尝试过使用XmlSerializerNamespaces,但是不允许我为第一个参数使用空字符串。我见过的所有例子都是根元素。我希望它适用于以下类设置。

[XmlRoot("item")]
public class Item
{
     [XmlElement("location")]
     public string Location { get;set; }
}

2 个答案:

答案 0 :(得分:0)

您也可以为元素指定命名空间,试试这个

[XmlRoot("item")] public class Item { [XmlElement(ElementName = "location", Namespace="Athens")] public string Location { get;set; } }

答案 1 :(得分:0)

您可以在您的类中嵌入一个XElement值的属性,该属性按需填充必要的命名空间和值,然后使用XmlAnyElementAttribute属性对其进行修饰,以告知XmlSerializer包含它就像最终的XML一样:

[XmlRoot("item" /*, Namespace = "" */)] // Applies when an Item is the document root.
[XmlType("item" /*, Namespace = "" */)] // Applies when an Item is not the document root.
public class Item
{
    [XmlIgnore]
    public string Location { get; set; }

    [XmlIgnore]
    public string LocationNamespace { get; set; }

    [XmlAnyElement]
    public XElement LocationElement
    {
        get
        {
            var ns = (XNamespace)LocationNamespace;
            var element = new XElement(ns + "location", Location);
            return element;
        }
        set
        {
            if (value == null)
            {
                LocationNamespace = Location = null;
            }
            else
            {
                LocationNamespace = value.Name.Namespace.NamespaceName;
                Location = value.Value;
            }
        }
    }
}

当放置(例如)在数组中时,以下类:

var items = new List<Item> { new Item { Location = true.ToString(), LocationNamespace = "Athens" } };

将被序列化为以下XML:

<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <item>
        <location xmlns="Athens">True</location>
    </item>
</ArrayOfItem>

<强>更新

您的更新问题需要每个Item中的一系列位置。您可以通过让XmlAnyElement返回XElements数组:

来实现
public class Item
{
    public Item()
    {
        this.Locations = new List<string>();
    }

    [XmlIgnore]
    public List<string> Locations { get; set; }

    [XmlIgnore]
    public string Location { get; set; }

    [XmlAnyElement]
    public XElement [] LocationElements {
        get
        {
            var elements = Locations.Select(l => new XElement(XName.Get("location", l), (l == Location).ToString())).ToArray();
            return elements;
        }
        set
        {
            Locations = value.Select(el => el.Name.Namespace.NamespaceName).ToList();
            Location = value.Where(el => bool.Parse(el.Value)).Select(el => el.Name.Namespace.NamespaceName).Distinct().SingleOrDefault() ?? string.Empty;
        }
    }
}

然后是以下

        var cities = new List<string> { "Athens", "London", "Salt Lake City" };
        var items = new List<Item> { new Item { Locations = cities, Location = cities[0] }, new Item { Locations = cities, Location = cities[1] } };

生成以下XML:

<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <item>
        <location xmlns="Athens">True</location>
        <location xmlns="London">False</location>
        <location xmlns="Salt Lake City">False</location>
    </item>
    <item>
        <location xmlns="Athens">False</location>
        <location xmlns="London">True</location>
        <location xmlns="Salt Lake City">False</location>
    </item>
</ArrayOfItem>