Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read in some XML then split out various nodes/elements in .NET?

Tags:

c#

.net

xml

I have some xml (in a file, but can be a string) which I need to parse, e.g.:

var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xmlText);

Given the following XML:

<foo>
    <cat>...</cat>
    <cat>...</cat>
    <dog>...</dog>
    <cat>...</cat>
    <dog>...</dog>
</foo>

I'm not sure how I can extract all the cat and dog elements and put them into the following output :-

<foo>
    <cat>...</cat>
    <cat>...</cat>
    ....
</foo>

and the same with dogs.

What's the trick to extract those nodes and put them into separate XMLDocuments.

like image 206
Pure.Krome Avatar asked Oct 01 '13 06:10

Pure.Krome


2 Answers

Use Linq to XML as it has a much nicer API.

var doc = XElement.Parse(
@"<foo>
    <cat>...</cat>
    <cat>...</cat>
    <dog>...</dog>
    <cat>...</cat>
    <dog>...</dog>
</foo>");
doc.Descendants("dog").Remove();

doc now contains this:

<foo>
    <cat>...</cat>
    <cat>...</cat>
    <cat>...</cat>
</foo>

Edit:

While Linq to XML itself provides a nice API to work with XML, the power of Linq and its projection capabilities enables you to shape your data as you see fit.

Consider this, for example. Here the descendant elements are grouped by name and projected into a new root element which is then wrapped into a XDocument. Note that this creates an enumerable of XDocument.

var docs= 
    from d in doc.Descendants()
    group d by d.Name into g
    select new XDocument(
        new XElement("root", g)
    );

docs now contains:

<root>
    <cat>...</cat>
    <cat>...</cat>
    <cat>...</cat>
</root>
---
<root>
    <dog>...</dog>
    <dog>...</dog>
</root> 

Oh, by the way. The Descendants method goes through all descendant elements, use Elements if you only want the immediate child elements.

Here are the Linq to XML docs on MSDN

like image 52
Mikael Östberg Avatar answered Oct 20 '22 11:10

Mikael Östberg


The easiest way will be to use XSLT and apply it on you XMLDocument in such way you won't modify your source and have as much outputs as you need.

The code for applying transform is

    XslCompiledTransform xslTransform = new XslCompiledTransform();
    StringWriter writer = new StringWriter();          
    xslTransform.Load("cat.xslt");
    xslTransform.Transform(doc.CreateNavigator(),null, writer);
    return writer.ToString();

And the simple cat.xslt is

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="foo">
        <xsl:copy>
            <xsl:copy-of select = "cat" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
like image 2
Piotr Stapp Avatar answered Oct 20 '22 12:10

Piotr Stapp