I'm traversing a large XML document using XmlReader
and stitching it into a much smaller and more manageable XmlDocmuent
. Along the way, I find a node that's interesting so to move it I do this:
targetDoc.LoadXml("<result></result>");
// Some interesting code removed
using (XmlReader r = XmlReader.Create(file))
{
while (r.Read())
{
if (r.NodeType == XmlNodeType.Element)
{
if (r.Name == match)
{
// Put the node into the target document
targetDoc.FirstChild.InnerXml = r.ReadOuterXml();
return targetDoc;
}
}
}
}
This is all well and good, except I'd like to include the node without its descendents. What I'm interested in is the node itself with its attributes. The descendents are very large, bulky and uninteresting at this point. (And reading them into memory all at once will cause out of memory errors...)
Is there an easy way to get the text (?) of the found element with its attributes -- but not its descendents -- into the target document?
I don't think there's a Built-in way of doing it. I think you have to read out the Attributes and content yourself.
e.g.
static void Main(string[] args)
{
var xml = @"<root>
<parent a1 = 'foo' a2 = 'bar'>Some Parent text
<child a3 = 'frob' a2= 'brob'> Some Child Text
</child>
</parent>
</root>";
var file = new StringReader(xml) ;
using (XmlReader r = XmlReader.Create(file))
{
while (r.Read())
{
if (r.NodeType == XmlNodeType.Element)
{
if (r.Name == "parent")
{
var output = new StringBuilder();
var settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
using (var elementWriter = XmlWriter.Create(output, settings))
{
elementWriter.WriteStartElement(r.Name);
elementWriter.WriteAttributes(r,false);
elementWriter.WriteValue(r.ReadString());
elementWriter.WriteEndElement();
}
Console.WriteLine(output.ToString());
}
}
}
}
if (System.Diagnostics.Debugger.IsAttached)
Console.ReadLine();
}
Will produce
<parent a1="foo" a2="bar">Some Parent text</parent>
Press any key to continue . . .