2009-09-21 79 views
2

我有一个包含以下结构的XML文档:C#,插入强类型对象到XML文档元素

它或多或少活动的集合:

<Events> 
    <Event> 
    <DateTime></DateTime> 
    <EventType></EventType> 
    <Result></Result> 
    <Provider></Provider> 
    <ErrorMessage></ErrorMessage> 
    <InnerException></InnerException> 
    </Event> 
</Events> 

在C#中我有持久化对象称为事件:

现在给出该文件已经存在,并保存到文件...我呼吁:

 XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.Load(dataPath); 

现在如何添加一个新的事件项目到事件?

我在我的C#代码中有一个强类型的事件项,并且希望它作为最后一个孩子插入XML对象的Events集合中。

我想这就是我要问的:https://stackoverflow.com/questions/1457033/c-insert-a-strongly-typed-object-as-node-in-existing-xml-document

+0

是您'Event'类已经准备与'XmlSerializer'使用吗? – 2009-09-21 21:43:44

+0

活动课很好。只需要最好的方法来将事件对象添加为事件的子... – 2009-09-21 21:45:59

回答

1

只需使用XmlDocument手动编写代码即可。您可以将转换或插入的类添加到要保存的文档中。

这是基于.net 2的限制。0和你在这些评论说:

  • @Fred,我想尝试减少写入时间,因此,在这个应用程序,文件的机会就越少不写一下子,少写时间的原因腐败。 - JL 16分钟前
  • 为什么你认为你有很多文件损坏的机会? - 弗雷德里克Gheysels 9分钟前
  • 从现有的代码测试结果我已经使用序列化作为一个整体。
1

如果您使用的是.NET 3.5,你可以使用LINQ到XML,像下面的工作

XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"), 
new XComment("Event document"), 
new XElement("Events", 
    new XElement ("Event", 
     new XElement("DateTime", event.DateTime), 
     new XElement("EventType", event.EventType), 
     new XElement("Result", event.Result), 
     new XElement("Provider", event.Provider), 
     new XElement("ErrorMessage", event.ErrorMessage), 
     new XElement("InnerException", event.InnerException) 
    ) 
)); 


doc.Save(@"c:\sample.xml"); 

如果你有一个现有的xml文档需要附加到如下所示的内容。

XDocument doc = XDocument.Load(@"c:\sample.xml"); 
XElement events = doc.Element(XName.Get("Events")); 
events.Add(new XElement ("Event", 
     new XElement("DateTime", event.DateTime), 
     new XElement("EventType", event.EventType), 
     new XElement("Result", event.Result), 
     new XElement("Provider", event.Provider), 
     new XElement("ErrorMessage", event.ErrorMessage), 
     new XElement("InnerException", event.InnerException) 
)); 

doc.Save(@"c:\sample.xml"); 
+0

糟糕,忘了提及我被困在.net v2项目中。 – 2009-09-21 21:02:42

3

看看Xml序列化属性。

你可以这样做:

[XmlRoot("Event")] 
public class Event 
{ 

    [XmlElement("DateTime")] 
    public string DateTime 
    { 
     get; 
     set; 
    } 

    [XmlElement("EventType")] 
    public EnumReportingEventType EventType 
    { 
     get; 
     set; 
    } 

    [XmlElement("Result")] 
    public EnumReportingResult Result 
    { 
     get; 
     set; 
    } 

    [XmlElement("Provider")] 
    public string Provider 
    { 
     get; 
     set; 
    } 

    [XmlElement("ErrorMessage")] 
    public string ErrorMessage 
    { 
     get; 
     set; 
    } 

    [XmlElement("InnerException")] 
    public string InnerException 
    { 
     get; 
     set; 
    } 
} 

事实上,如果你的类的属性具有相同的名称作为您的XML元素,您不必使用的XmlElement属性。

然后,您可以使用XmlSerializer来序列化和反序列化。

编辑: 然后,创建一个代表存储在现有xml中的整个类型的类型不是更好吗?
反序列化它,给附加属性赋值,并将其序列化回来?

+0

这很好,我真正需要的是如何将强类型文档转换为已存在的文档结构。 – 2009-09-21 21:09:11

+0

你究竟是什么意思?我想我不明白你想说什么... – 2009-09-21 21:11:59

+0

好的 - 我会更新问题... – 2009-09-21 21:12:55

1

插入的XmlElement场附近的“事件”类的结尾,像这样:

[System.Xml.Serialization.XmlAnyElementAttribute()] 
public System.Xml.XmlElement Any { get; set } 

您可以将其命名为任何你想要的,只要你有它的“XmlAnyElementAttribute”。

您可以使用类似下面的一个强类型的对象序列化到这个领域:

MyParentObject parent = new MyParentObject(){ ... }; 

MyObject obj = new MyObject(){ /*... initialize*/ }; 
XmlSerializer ser = new XmlSerializer(typeof(MyObject)); 
XmlDocument doc = new XmlDocument(); 

using (StringWriter sw = new StringWriter()) 
{ 
    ser.Serialize(sw, obj); 
    doc.LoadXml(sw.ToString()); 
} 

parent.Any = (XmlElement)doc.DocumentElement; 

序列化XML将很好地附加到你的类,它将事件包括正确的命名空间。

+0

这工作在.net 2.0 – 2009-09-21 21:31:41

+0

我可以从您的编辑看到,这个答案不回答你的问题!抱歉。 – 2009-09-21 21:44:16

+0

对不起,我第一次没有更清楚。希望现在它更有意义。 – 2009-09-21 21:48:54

0

你所希望做的是一样的东西:

doc.ChildNode[0].AppendChild(MethodToReturnADeserializedObject(event)); 

创建反序列化事件对象到XML节点的方法。然后使用AppendChild将它作为其子节点中的最后一个元素插入。

1

假设你Event类已经可以被序列化,你想用XmlSerializer的方式,你可以做到以下几点:

XmlSerializer ser = new XmlSerializer(typeof(Event)); 

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(dataPath); 

Event evt = ...; 

XmlDocument evtDoc = new XmlDocument(); 
using (XmlWriter writer = evtDoc.CreateNavigator().AppendChild()) 
{ 
    ser.Serialize(writer, evt); 
} 
XmlNode evtNode = evtDoc.RemoveChild(evtDoc.DocumentElement); 

XmlNode events = xmlDoc.SelectSingleNode("/Events"); 
events.AppendChild(evtNode); 
+0

好的,让我试试这个。 – 2009-09-21 22:00:53

+0

ser从哪里来? – 2009-09-21 22:16:16

+0

检查第一行代码。您可能希望将其设置为类中的“private static”字段,以免每次都重新创建序列化程序(可重用)。 – 2009-09-21 22:22:18