默认 xml 命名空间但不在根目录下使用 XmlSerializer
Default xml namespace but not on root using XmlSerializer
所以我正在做的是使用 XmlSerializer 并使用自定义 class。其中一个元素需要一个默认的命名空间和它自己的值。默认命名空间虽然需要是动态的。因此 Athens 是该位置元素的命名空间。下一个位置元素可能是伦敦。例如:
<items>
<item>
<location xmlns="Athens">True</location>
<location xmlns="London">False</location>
</item>
<items>
我尝试过使用 XmlSerializerNamespaces,但这不允许我对第一个参数使用空字符串。我看到的所有示例都是针对根元素的。我希望它适用于以下 class 设置。
[XmlRoot("item")]
public class Item
{
[XmlElement("location")]
public string Location { get;set; }
}
您也可以为元素指定命名空间,试试这个
[XmlRoot("item")]
public class Item
{
[XmlElement(ElementName = "location", Namespace="Athens")]
public string Location { get;set; }
}
您可以在您的 class 中嵌入一个 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;
}
}
}
}
当放置(例如)在数组中时,以下 classes:
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
return 一个 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>
所以我正在做的是使用 XmlSerializer 并使用自定义 class。其中一个元素需要一个默认的命名空间和它自己的值。默认命名空间虽然需要是动态的。因此 Athens 是该位置元素的命名空间。下一个位置元素可能是伦敦。例如:
<items>
<item>
<location xmlns="Athens">True</location>
<location xmlns="London">False</location>
</item>
<items>
我尝试过使用 XmlSerializerNamespaces,但这不允许我对第一个参数使用空字符串。我看到的所有示例都是针对根元素的。我希望它适用于以下 class 设置。
[XmlRoot("item")]
public class Item
{
[XmlElement("location")]
public string Location { get;set; }
}
您也可以为元素指定命名空间,试试这个
[XmlRoot("item")]
public class Item
{
[XmlElement(ElementName = "location", Namespace="Athens")]
public string Location { get;set; }
}
您可以在您的 class 中嵌入一个 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;
}
}
}
}
当放置(例如)在数组中时,以下 classes:
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
return 一个 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>