我有这些课程:
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>
注意:我要删除,而不是重命名。
答案 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");