C# XmlDocument RemoveChild(node) nagyon sokáig tart

C# XmlDocument RemoveChild(node) nagyon sokáig tart
2014-03-27T14:28:15+01:00
2014-03-31T17:46:16+02:00
2022-11-30T20:50:34+01:00
Tu Ati
Sziasztok 

Segítséget szeretnék kérni egy XmlDocument node törlésével kapcsolatban.
Van egy adatlap kitöltő programom, ami egy xml fájlt hoz létre a következő tartalommal:

<dataSheets> <dataSheet name="Fejléc" version="2013-07-01"> <data name="EL131100" convert="0" label="EL131100" value="123455564" /> <data name="EL132100" convert="0" label="EL132100" value="99" /> . . </dataSheet> <dataSheet name="adatlaprész1" version="2013-07-01"> <data name="AL121300" convert="0" label="AL121300" value="2013.12.31." /> <data name="AL121420" convert="0" label="AL121420" value="10" /> . . </dataSheet> <dataSheet name="adatlaprész2" version="2013-07-01"> <data name="PT112000" convert="0" label="PT112000" value="" /> <data name="PT113000" convert="0" label="PT113000" value="1" /> . . </dataSheet> <dataSheet name="Lábléc" version="2013-07-01"> <data name="AL123130" convert="0" label="AL123130" value="2012.12.15." /> <data name="EL131500" convert="0" label="EL131500" value="27-3165" /> . . </dataSheet> </dataSheets>


Az adatlaprész1 és 2-ből több is lehet a fájlban. Az esetek többségében 4-5-nél több nincs egy fájlban. Van olyan xml fájl amiben viszont pl. 150 is előfordul, így az xml fájlban a sorok száma kb. 7000

Ebben a fájlban amikor az adatlaprész1..n közül akarok törölni egyet, akkor a következő kódrészletben a node.ParentNode.RemoveChild(node) sor futásakor több percig áll a program, nem reagál semmire.

for (int intX = 0; intX < xmldocReportDocument.GetElementsByTagName("dataSheet").Count; intX++) if (xmldocReportDocument.GetElementsByTagName("dataSheet")[intX].Attributes.GetNamedItem("name").Value == strCurrentPageType) { intCurrentForm++; if (intCurrentForm == intLastSelectedNode) { xeInsertBefore = (XmlElement)xmldocReportDocument.GetElementsByTagName("dataSheet")[intX + 1]; xmldocReportDocument.GetElementsByTagName("dataSheet")[intX].ParentNode.RemoveChild(xmldocReportDocument.GetElementsByTagName("dataSheet")[intX]); // itt van a probléma!!! break; } }
A neten keresgéléssel a xmlNode törléssel csak mindig ez a fajta törlési megoldás található. 
A kérdésem az lenne, hogy miért várakozik ilyen sokáig a RemoveChild (ha csak pár adatlaprész1..10 van a fájlban, akkor pillanatok alatt lefut)?
Továbbá, hogy lehet-e esetleg más megoldással törölni, ami gyorsabban oldaná meg a törlést?

Előre is köszönöm a válaszaitokat: TuAti 
Mutasd a teljes hozzászólást!

  • Nem lenne rossz, ha összedobnál egy minta XML-file-t, megjelölve egy konkrét elemet, amit törölni kell, hogy reprodukálni lehessen a problémát.

    Hasraütésre nemhogy 7000 sor, hanem még 7000 node sem kéne, hogy probléma legyen.
    Mutasd a teljes hozzászólást!
  • a közvetlen dom manipuláció jellemzően memóriapazarló és lassú, simán lehet hogy a "gyári" lassúságot tudod kimérni.

    egy jobb alternatíva lehet, hogy beolvasod az xml-t, deszerializálod objektumgráffá a memóriában, azon megcsinálod a kívánt műveleteket, és a végén egyben visszaszerializálod xml-lé.
    Mutasd a teljes hozzászólást!
  • Én mindenféleképpen butaságnak tartom, hogy folyton hívogatod a GetElementsByTagName metódust. Ez minden hívásnál végig nézi az egész XML dokumentumot és egy listát gyárt belőle.

    Szerintem célszerű lenne csak egyszer meghívni és a továbbiakban a visszaadott listán dolgozni, valahogy így.

    XmlNodeList lista = xmldocReportDocument.GetElementsByTagName("dataSheet"); for (int intX = 0; intX < lista.Count; intX++) if (lista[intX].Attributes.GetNamedItem("name").Value == strCurrentPageType) { intCurrentForm++; if (intCurrentForm == intLastSelectedNode) { // Ez nem tudom minek ide //xeInsertBefore = (XmlElement)xmldocReportDocument.GetElementsByTagName("dataSheet")[intX + 1]; lista[intX].ParentNode.RemoveChild(lista[intX]); // itt van a probléma!!! break; } }
    Mutasd a teljes hozzászólást!
  • Köszönöm a választ, lehet, hogy ez a DOM manipuláció van a háttérben, közben míg a válaszok jöttek, átalakítottam a progit, hogy .ParentNode.ReplaceChild-al cseréltem az új adatlaprészt a régire, de akkor meg, amikor az új rész feltöltésekor egy XmlElement létrehozása után a SetAttribute metódusnál lassul be :(

    Merre felé nézzek utána a deszerilázálásnak, esetleg az én esetemben ez hogy nézne ki?
    Mutasd a teljes hozzászólást!
  • Jó, csinálok egyet és feltöltöm, köszi előre is a próbálgatást :) 
    egyébként, mondjuk, a <dataSheet name="adatlaprész2"...-őt kell kicserélnem ugyanarra a névre de más data ... value= értékekkel (egy WebBrowser-be betöltött html lapnak az input és select controlok értékei kerülnek a value Attribute-ba és a name azonosítja a html lap controljainak id-jét; ha változtatok a megnyitott html lapon, akkor mentéskor fut le egy adatlaprész törlés és utána a módosított html lap újraolvasásával létrejövő új adatlaprész XmlElement-jének a beszúrása)
    Mutasd a teljes hozzászólást!
  • Köszi az észrevételt, javítottam a kódot, de még így is lassú, sajnos
    Mutasd a teljes hozzászólást!
  • deszerializáláshoz: 
    XmlSerializer Class (System.Xml.Serialization)

    meg kell csinálnod azt az osztálystruktúrát, aminek az adatait az xml reprezentálja, feldekorálni mindenféle attribútumokkal az osztályokat (pl. hogy az osztály nevét hogyan fordítsa le XML elem névre, vagy hogy a kollekciókat hogyan kezelje). Aztán a Serializer.Deserialize - vel be tudod olvasni az XML-t, ez egy objektumgráfot fog visszaadni amivel azt csinálsz amit akarsz, Serializer.Serialize -vel pedig ezt vissza tudod alakítani XML-lé.

    De ha nem akarsz ezzel vacakolni (vannak olyan XML struktúrák amiket nem jól kezel), akkor az is elég, ha beolvasod az XML-t, DOM műveletekkel feldolgozod, csinálsz belőle saját osztályokat, aztán azokat manipulálod, a végén pedig stringműveletekkel kiírod őket XML formában...
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd