c# - Replace part of large XML file -


i have large xml file, , need replace elements name (and inner elements) element. example - if element e:

<a> <b></b> <e>    <b></b>    <c></c> </e> </a> 

after replace e elem:

<a> <b></b> <elem></elem> </a> 

update: try use xdocument xml size more 2gb , have systemoutofmemoryexception

update2: code, xml not transform

xmlreader reader = xmlreader.create("xml_file.xml"); xmlwriter wr = xmlwriter.create(console.out); while (reader.read())    {        if (reader.nodetype == xmlnodetype.element && reader.name == "e")        {            wr.writeelementstring("elem", "val1");            reader.readsubtree();        }             wr.writenode(reader, false);    } wr.close(); 

update 3:

<a> <b></b> <e>    <b></b>    <c></c> </e> <i>   <e>     <b></b>     <c></c>   </e> </i>  </a> 

taking inspiration this blog post, can stream contents of xmlreader straight xmlwriter example code, handling node types. using writenode, in example code, add node and child nodes, wouldn't able handle each descendant in source xml.

in addition, need make sure read end of element want skip - readsubtree creates xmlreader this, doesn't reading. need ensure read end.

the resulting code might this:

using (var reader = xmlreader.create(new stringreader(xml), rs)) using (var writer = xmlwriter.create(console.out, ws)) {     while (reader.read())     {         switch (reader.nodetype)         {             case xmlnodetype.element:                 var subtreereader = reader.readsubtree();                 if (handleelement(reader, writer))                 {                     readtoend(subtreereader);                 }                 else                 {                     writer.writestartelement(reader.prefix, reader.localname, reader.namespaceuri);                     writer.writeattributes(reader, true);                     if (reader.isemptyelement)                     {                         writer.writeendelement();                     }                 }                 break;             case xmlnodetype.text:                 writer.writestring(reader.value);                 break;             case xmlnodetype.whitespace:             case xmlnodetype.significantwhitespace:                 writer.writewhitespace(reader.value);                 break;             case xmlnodetype.cdata:                 writer.writecdata(reader.value);                 break;             case xmlnodetype.entityreference:                 writer.writeentityref(reader.name);                 break;             case xmlnodetype.xmldeclaration:             case xmlnodetype.processinginstruction:                 writer.writeprocessinginstruction(reader.name, reader.value);                 break;             case xmlnodetype.documenttype:                 writer.writedoctype(reader.name, reader.getattribute("public"), reader.getattribute("system"), reader.value);                 break;             case xmlnodetype.comment:                 writer.writecomment(reader.value);                 break;             case xmlnodetype.endelement:                 writer.writefullendelement();                 break;         }     }     }  private static void readtoend(xmlreader reader) {     while (!reader.eof)     {         reader.read();     } } 

obviously put whatever logic inside handleelement, returning true if element handled (and therefore ignored). implementation logic in example code be:

private static bool handleelement(xmlreader reader, xmlwriter writer) {     if (reader.name == "e")     {         writer.writeelementstring("element", "val1");         return true;     }      return false; } 

here working demo: https://dotnetfiddle.net/ffibu4


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -