2009-09-21 78 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