How to use LINQ to get data from an XML file? - c#

I have xml files which look like this:
<?xml version="1.0" encoding="utf-8"?>
<record id="177" restricted="false">
<type>record type</type>
<startdate>2000-10-10</startdate>
<enddate>2014-02-01</enddate>
<titles>
<title xml:lang="en" type="main">Main title</title>
<!-- only one title element with type main -->
<title xml:lang="de" type="official">German title</title>
<!-- can have more titles of type official -->
</titles>
<description>description of the record</description>
<categories>
<category id="122">
<name>category name</name>
<description>category description</description>
</category>
<!-- can have more categories -->
</categories>
<tags>
<tag id="5434">
<name>tag name</name>
<description>tag description</description>
</tag>
<!-- can have more tags -->
</tags>
</record>
How do I select the data from these xml files using LINQ, or should I use something else?

You can load xml into XDocument objects using either the Load() method
for files, or the Parse() method for strings:
var doc = XDocument.Load("your-file.xml");
// OR
var doc = XDocument.Parse(yourXmlString);
Then you can access the data using LINQ:
var titles =
from title in doc.XPathSelectElements("//title")
where title.Attribute("type").Value == "official"
select title.Value;

Was searching for examples of Xmlserializer and found this: How to Deserialize XML document
So why not to try. I did Ctrl+C and Edit -> Paste Special -> Paste XML As Classes in Visual Studio 2013 and... Whoa I got all the classes generated. One condition target framework must be 4.5 and this function is available from Visual Studio 2012+ (as stated in that post)

Related

Reading and Editing XML file

I have an XML file which contains employee details. How can i edit the existing employee names in that MXL file using C# .NET.
Here is the xml file.
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee id="1">
<Name>Employee 1</Name>
<Designation>SE </Designation>
<Qualification>MCA </Qualification>
</Employee>
<Employee id="2">
<Name>Employee 2</Name>
<Designation>SE </Designation>
<Qualification>MCA </Qualification>
</Employee>
<Employee id="3">
<Name>Employee 3</Name>
<Designation>SE </Designation>
<Qualification>MCA </Qualification>
</Employee>
</Employees>
How can i edit the employee names. I am new to xml. For example using Console Application
You can simple do that using Linq to Xml.
using System.Xml.Linq;
...
XDocument xDoc = XDocument.Load(#"Your xml file path goes here"); // or XDocument.Parse("Your xml string goes here");
xDoc.Root.Elements("Employee").First(xe => xe.Attribute("id").Value == "1").Element("Name").Value = "your value";
Here is a good reference for head start: Programming Guide (LINQ to XML)
you can use XML Serialization, in my opinion this is the most comfortable way
of working with c# and xml,
some examples are here:
http://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

Extracting App version number from XML with C#

I have an XML file as follows. I would like to extract the Version number from this file.
I tried XML parsing. But, that is for node values only. I am able to get this file as string as follows. var doc = XDocument.Load("WMAppManifest.xml");
<?xml version="1.0" encoding="utf-8"?>
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2012/deployment" AppPlatformVersion="8.0">
<DefaultLanguage xmlns="" code="en-US" />
<App xmlns="" ProductID="{a3f55b1e-c183-4645-9b19-87a41a206978}" Title="sometitle" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="M-Files author" BitsPerPixel="32" Description="Apache Cordova for Windows Phone" Publisher="CordovaExample" PublisherID="{b93a0d8e-5aa9-4d9b-b232-17e2d852e779}">
<IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
</App>
</Deployment>
You can access the XML declaration node as follows:
XmlDeclaration declaration = doc.ChildNodes
.OfType<XmlDeclaration>()
.FirstOrDefault();
You can then read the value of declaration.Version.
Or, if you are after the 'app' version attribute in the XML document itself, try the following
string version = doc.Descendants("App")
.Single()
.Attribute("Version").Value

How to Split an XML file into multiple XML Files

I am trying to split a XML file to multiple small xml files in C#.net and am
trying to get the best possible approach to this. Any help on this will be
great... Sample example on what I am trying to do...
Source XML document
<?xml version="1.0" standalone="yes"?>
<DATABASE>
<DOC>
<DOCID>8510188</DOCID>
<ISSUE>2010</ISSUE>
<CAT>Literature and Art</CAT>
<TITLE>Test</TITLE>
<TEXT>Test</TEXT>
</DOC>
<DOC>
<DOCID>1510179</DOCID>
<ISSUE>2012</ISSUE>
<CAT>Miscellaneous</CAT>
<TITLE>Test</TITLE>
<TEXT>Test</TEXT>
</DOC>
</DATABASE>
Should split to two xml documents as below
1)
<?xml version="1.0" standalone="yes"?>
<DATABASE>
<DOC>
<DOCID>8510188</DOCID>
<ISSUE>2010</ISSUE>
<CAT>Literature and Art</CAT>
<TITLE>Test</TITLE>
<TEXT>Test</TEXT>
</DOC>
</DATABASE>
2)
<?xml version="1.0" standalone="yes"?>
<DATABASE>
<DOC>
<DOCID>1510179</DOCID>
<ISSUE>2012</ISSUE>
<CAT>Miscellaneous</CAT>
<TITLE>Test</TITLE>
<TEXT>Test</TEXT>
</DOC>
</DATABASE>
Well, I'd use LINQ to XML:
XDocument doc = XDocument.Load("test.xml");
var newDocs = doc.Descendants("DOC")
.Select(d => new XDocument(new XElement("DATABASE", d)));
foreach (var newDoc in newDocs)
{
newDoc.Save(/* work out filename here */);
}
(I'm assuming you want to save them. Maybe you don't need to. I've tested this just by printing them out to the console instead.)

Reading different XML with C#/DOM

I am currently using DOM to navigate xml in my C# project. However, some XML that i've come across lately is a bit different.
whereas usually I have:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<entry>
<author>
<name>Me =)</name>
</author>
<content>
<somefield1>
<Subfield>subfield data</subfield>
</somefield>
</content>
</entry>
</feed>
and can navigate using foreach entry as entry, selectsinglenode(/content/somefield1/subfield), innertext to get the data from the subfield for each entry, the new XML looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
<atom:entry>
<atom:author>
<name>Me =)</name>
</atom:author>
<atom:content>
<somefield1>
<Subfield>subfield data</subfield>
</somefield>
</atom:content>
</atom:entry>
</atom:feed>
selectsinglenode(/atom:content/somefield1/subfield) is definitely not going to work...any suggestions?
atom: is just the namespace, and possibly you might just ignore it. If it still not works, you may have to use:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("atom", "http://www.w3.org/2005/Atom");
selectsinglenode("atom:content/somefield1/subfield", nsmgr);
Which is documented here

Create a new XMLDocument by filtering an existing document in c# using xpath

I have a situation where I receive an XML (document) file from an external company. I need to filter the document to remove all data I am not interested in.
The file is about 500KB but will be requested very often.
let say the following file:
<dvdlist>
<dvd>
<title>title 1</title>
<director>directory 2</director>
<price>1</price>
<location>
<city>denver</city>
</location>
</dvd>
<dvd>
<title>title 2</title>
<director>directory 2</director>
<price>2</price>
<location>
<city>london</city>
</location>
</dvd>
<dvd>
<title>title 3</title>
<director>directory 3</director>
<price>3</price>
<location>
<city>london</city>
</location>
</dvd>
</dvdlist>
What I need is simply filter the document based on the city = london in order to end up with this new XML document
<dvdlist>
<dvd>
<title>title 2</title>
<director>directory 2</director>
<price>2</price>
<location>
<city>london</city>
</location>
</dvd>
<dvd>
<title>title 3</title>
<director>directory 3</director>
<price>3</price>
<location>
<city>london</city>
</location>
</dvd>
</dvdlist>
I have tried the following
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\Development\Website\dvds.xml");
XmlNode node = doc.SelectSingleNode("dvdlist/dvd/location/city[text()='london']");
Any help or links will appreciate
Thanks
XPath is a selection expression language -- it never modifies the XML document(s) it operates on.
Therefore, in order to obtain the desired new XML document, you need to either use XML DOM (not recommended) or apply an XSLT transformation to the XML document. The latter is the recommended way to go, since XSLT is a language especially designed for tree transformations.
In .NET one can use the XslCompiledTransform class and its Transform() method. Read more about these in the relevant MSDN documentation.
The XSLT transformation itself is extremely simple:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dvd[not(location/city='london')]"/>
</xsl:stylesheet>
Here, you can find a complete code example how to obtain the result of the transformation as an XmlDocument (or if desired, as an XDocument).
Here's an example using LINQ to XML.
//load the document
var document = XDocument.Load(#"C:\Development\Website\dvds.xml");
//get all dvd nodes
var dvds = document.Descendants().Where(node => node.Name == "dvd");
//get all dvd nodes that have a city node with a value of "london"
var londonDVDs = dvds.Where(dvd => dvd.Descendants().Any(child => child.Name == "city" && child.Value == "london"));

Categories

Resources