将List <t>序列化为现有XML文档时如何删除<arrayofx>容器元素

时间:2018-08-31 04:27:06

标签: c# asp.net xml serialization linq-to-xml

我有这些课程:

public class WikiEntry
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    [XmlArray]
    public List<Category> Categories { get; set; }
}

public class Category
{
    [XmlAttribute]
    public string Id { get; set; }
    [XmlAttribute]
    public string Text { get; set; }
}

一开始我就具有以下XML结构:

<Wiki>
  <Categories></Categories>
  <Tags></Tags>
  <WikiEntries></WikiEntries>
</Wiki>

我正在序列化wiki.Categories并将其添加到现有XML中,如下所示:

var xDoc = XDocument.Load("Data.xml");

WikiEntry wiki = new WikiEntry
{
   Id = Guid.NewGuid().ToString(),
   Title = "Simple title",
   Content = "Simple content here",
   Categories = new List<Category>
     {
       new Category
       {
         Id = Guid.NewGuid().ToString(),
         Text = "CATEGORYA"
       },
       new Category
       {
         Id = Guid.NewGuid().ToString(),
         Text = "CATEGORYB"
       }
    }
};

var categories = xDoc.Root.Element("Categories");

var categoriesBuilder = new StringBuilder();

using (var writer = XmlWriter.Create(categoriesBuilder, new XmlWriterSettings { Indent = true, ConformanceLevel = ConformanceLevel.Auto, OmitXmlDeclaration = true }))
        {
            var ns = new XmlSerializerNamespaces();
            ns.Add("", "");

            var xs = new XmlSerializer(typeof(List<Category>), "");

            xs.Serialize(writer, wiki.Categories, ns);
        }

categories.Add(XElement.Parse(categoriesBuilder.ToString().Trim()));
xDoc.Save(file);

问题是当我这样做时:

<Categories>
 <ArrayOfCategory>
   <Category Id="482ce9f6-5d4c-48f9-b84f-33c3cf9b0b0f" Text="CATEGORYA" />
   <Category Id="73e6c671-fb6d-40a4-8694-1d5dbcf381d5" Text="CATEGORYB" />
 </ArrayOfCategory>
 <ArrayOfCategory>
   <Category Id="3c0f2a15-4623-4f33-b356-75e8c8b89624" Text="CATEGORYA" />
   <Category Id="d8720ca9-06f5-401d-90e2-c7f43e1c91f5" Text="CATEGORYB" />
 </ArrayOfCategory>

所以,我的问题是如何序列化我的Category类,以便得到它(忽略<ArrayOfCategory>父对象):

  <Categories>
      <Category Id="482ce9f6-5d4c-48f9-b84f-33c3cf9b0b0f" Text="CATEGORYA" />
      <Category Id="73e6c671-fb6d-40a4-8694-1d5dbcf381d5" Text="CATEGORYB" />
      <Category Id="3c0f2a15-4623-4f33-b356-75e8c8b89624" Text="CATEGORYA" />
      <Category Id="d8720ca9-06f5-401d-90e2-c7f43e1c91f5" Text="CATEGORYB" />
  </Categories>

注意:我要删除,而不是重命名。

3 个答案:

答案 0 :(得分:1)

您可以使用XContainer.CreateWriter()直接序列化为false。这样一来,您就可以直接序列化为XDocument元素的子元素XElement,而无需任何中间字符串表示形式。

首先,定义以下扩展方法:

categories

现在,您可以将public static class XObjectExtensions { public static XElement SerializeToXElement<T>(this T obj, XContainer parent = null, XmlSerializer serializer = null, XmlSerializerNamespaces ns = null) { if (obj == null) throw new ArgumentNullException(); // Initially, write to a fresh XDocument to cleanly avoid the exception described in // https://stackoverflow.com/questions/19045921/net-xmlserialize-throws-writestartdocument-cannot-be-called-on-writers-created var doc = new XDocument(); using (var writer = doc.CreateWriter()) { (serializer ?? new XmlSerializer(obj.GetType())).Serialize(writer, obj, ns ?? NoStandardXmlNamespaces()); } // Now move to the incoming parent. var element = doc.Root; if (element != null) { element.Remove(); if (parent != null) { parent.Add(element); } } return element; } public static XmlSerializerNamespaces NoStandardXmlNamespaces() { var ns = new XmlSerializerNamespaces(); ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines. return ns; } } 中的Categories添加到WikiEntry中,如下所示:

xDoc

工作示例.Net小提琴here

答案 1 :(得分:0)

将根名称作为参数传递给grep 'def say_hi(name)' -A 2 -nr directory | grep -v 'return "Hi #{name}!"' 调用就可以解决问题。

XMLSerializer

答案 2 :(得分:0)

这里有一些Linq-to-Xml可以实现您所需要的:

categories.Add(XElement.Parse(categoriesBuilder.ToString().Trim()));


XDocument output =
new XDocument(
    new XElement(xDoc.Root.Name,
        new XElement("Categories",
            from comp in xDoc.Root.Elements("Categories").Elements("ArrayOfCategory").Elements("Category")
            select new XElement("Category",
                new XAttribute("Id", comp.Attribute("Id").Value),
                new XAttribute("Text", comp.Attribute("Text").Value)
            ))));




output.Save("c:\\so\\test.xml");