Jak dopisać dane do istniejącego pliku XML

02 lipca 2007, 22:20

KomentarzeKomentarze: 5 KategorieKategorie: .nettips

Od jakiegoś czasu (o ile mam ten czas) przepisuję na nowo XmlBloga. Tym razem chcę skorzystać z klasy XMLWriter, a nie jak do tej pory XmlDocument. Dlaczego z tej klasy? Otóż pozwala ona bardziej panować nad tym co i w jaki sposób jest zapisywane do pliku XML.

Ponadto dzięki tej klasie mogę dopisywać kolejne dane na koniec istniejącego pliku bez wczytywania całości. Jest to dosyć istotne, aby zwiększyć wydajność i przy większej ilości postów nie wczytywać ich wszystkich do pamięci. Zwłaszcza kiedy na stronie wyświetlamy tylko kilka ostatnich.

Poniżej prezentuję prototyp metody zapisującej dane w XMLBlogu w nowej wersji.

   1:  public static void SerializeAndSaveList(IXWriterObject obj)
   2:  {
   3:      string objectTag = obj.GetTag();
   4:      string file = Utils.GetListFileNameForObject(obj);
   5:      file = Path.Combine(XimiManager.DataDirectory, file);
   6:      using (FileStream f = new FileStream(file, FileMode.Open, FileAccess.Write))
   7:      {
   8:          f.Seek(-(objectTag.Length), SeekOrigin.End);
   9:          using (StreamWriter closer = new StreamWriter(f))
  10:          {
  11:              XmlWriter writer = XmlWriter.Create(closer, Utils.WriterSettings);
  12:              obj.Write(writer);
  13:              writer.WriteRaw("\r\n" + objectTag);
  14:              writer.Flush();
  15:          }
  16:      }
  17:  }

Metoda przyjmuje obiekt, który implementuje interface IXWriterObject. Interface ten eksponuje jedną metodę Write, która wpisuje treść do pliku.

Samo dopisanie danych na końcu pliku jest możliwe kiedy go otworzymy i przesuniemy pozycję w strumieniu na koniec (SeekOrigin.End) oraz cofniemy się w stronę początku o tyle znaków z ilu składa się tag zamykający dany plik XML. Na przykład </blogs>. W tym przypadku do pobrania tego tagu korzystam z metody statycznej GetListEndTagForType z klasy Util.

To już w sumie wszystko, a może da się optymalniej? :)

 

Ten artykuł jest widoczny także na: ZINE.NET

Jeśli spodobał Ci się ten artykuł, to podziel się tą informacją z innymi.

Gravatar
Michał Andruchów
2007-07-26 17:47

Mam sugestię. Czy użycie LINQ z XML, dostępne w najnowszej Beta wersji Visual C# Orcas, nie było by łatwiejsze?

Tam też masz kontrolę gdzie dodajesz węzeł (koniec, początek), przyjemne i łatwe do opanowania kodowanie

Pozdrawiam

Gravatar
gagarin
2010-04-30 21:38

Nie wiem czy optymalniej, ale na pewno prościej.

Klasa System.Xml, np. dodawanie linku i tytułu do pliku xml (rss):

XmlDocument channelsDoc = new XmlDocument();

channelsDoc.Load("RssChannels.xml");

foreach (RssInfo item in rssList)

{

XmlNode channels = channelsDoc.SelectSingleNode("channels");

XmlNode newChannel = channelsDoc.CreateNode(XmlNodeType.Element, "channel", null);

XmlNode name = channelsDoc.CreateNode(XmlNodeType.Element, "name", null);

name.InnerText = item.Nazwa;

XmlNode link = channelsDoc.CreateNode(XmlNodeType.Element, "link", null);

link.InnerText = item.Link;

newChannel.AppendChild(name);

newChannel.AppendChild(link);

channelsDoc.DocumentElement.AppendChild(newChannel);

}

channelsDoc.Save("RssChannels.xml");

żadnego cofania się o ileś znaków w pliku, itp.

Gravatar
dario-g
2010-05-02 16:23

Oczywiście żadnego cofania się, ale zależało mi właśnie na tym, aby nie używać XmlDocument, gdyż metoda Load ładuje cały plik naraz.

Gravatar
Robert
2010-05-05 22:47

Cześć czy ktoś mógł by mi pomóc bo nie mogę sobie poradzić z tym dopisywaniem mam taką bazę:

<Artykuly>

<Artykul d2p1:id="" xmlns:d2p1="1">

<Nazwa>sdfsdf</Nazwa>

<Ilosc>dfgdfg</Ilosc>

<Data>13-12-3112</Data>

<Cena>123</Cena>

</Artykul>

</Artykuly>

i chcę dopisać następny artykuł i czy to będzie wyglądać tak?

XmlDocument xmldoc = new XmlDocument();

xmldoc.Load("sklep.xml");

foreach (string dane in xmldoc)

{

XmlNode nazwa = xmldoc.SelectSingleNode("Nazwa");

XmlNode nowanazwa = xmldoc.CreateNode(XmlNodeType.Element, "Nazwa", null);

XmlNode ilosc = xmldoc.SelectSingleNode("Ilosc");

XmlNode nowailosc = xmldoc.CreateNode(XmlNodeType.Element, "Ilosc", null);

XmlNode data = xmldoc.SelectSingleNode("Data");

XmlNode nowadata = xmldoc.CreateNode(XmlNodeType.Element, "Data", null);

XmlNode cena = xmldoc.SelectSingleNode("Cena");

XmlNode nowacena = xmldoc.CreateNode(XmlNodeType.Element, "Cena", null);

}

Nie mam zielonego pojęcia jak to zrobić, raczej to nie będzie tak

bo nawet mi się nie kompiluje. POMOCY!

Gravatar
dario-g
2010-05-05 23:57

Robert:

Podeślij ten kawałek kodu na mój adres e-mail. Zerknie się :)

Dodaj komentarz Dodaj komentarz

Twój email (niepublikowany/opcjonalnie):

Twoja strona (opcjonalnie):

Imię i nazwisko/nick (wymagane):

Treść (wymagane):

Chcę być poinformowany o kolejnych komentarzach:

Te pola zostaw puste

Uwaga! Zastrzegam sobie prawo do usuwania obraźliwych i wulgarnych komentarzy.