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
Post a Comment