XML to Linq C# retrieve entries from XML - c#

I need to to the following task:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Eintrag>
<Kunde>
<Email> example#test.de </Email>
<Kundennummer>1234567 </Kundennummer>
</Kunde>
<Kunde>
<Email> example1#test.de </Email>
<Kundennummer>1234569 </Kundennummer>
</Kunde>
</Eintrag>
I need to save Email and Kundennummer of each Kunde in a String.
Can you please tell me how to do it?

Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication62
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("Kunde").Select(x => new
{
email = (string)x.Element("Email"),
num = (string)x.Element("Kundennummer")
}).ToList();
}
}
}

Related

How do I get SOAP xml file data using LINQ and display it in a form's text box? C#

How do I do it?
This is the SOAP XML file
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2001/12/soap-envelope" soapenv:encodingStyle="http://www.w3.org/2001/12/soap-encoding" >
<soapenv:Body xmlns:lle="http://www.aab.org/logevents" >
<lle:Events>
<lle:eventid>ID1</lle:eventid>
<lle:tweet>
<lle:text>This is some tweet in my day</lle:text>
<lle:location>
<lle:lat>66</lle:lat>
<lle:long>77</lle:long>
</lle:location>
<lle:datetimestamp>datetimestamp</lle:datetimestamp>
</lle:tweet>
</lle:Events>
</soapenv:Body>
</soapenv:Envelope>
And this is my C# code, it doesn't display anything in the text box, I have tried adding the "lle:" in front of "Event" and its Descendants like:
.Descendants("lle:Events")
select events.Element("lle:eventid").Value;
but apparently it doesn't work, and there's lots of errors, so I changed it back
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
namespace Xmltest
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
XDocument xmlDocument = new XDocument();
IEnumerable<string> id = from events in XDocument.Load(#"C:\Users\Jack\source\repos\xmltest\Xmltest\XmlFile.xml")
.Descendants("Events")
select events.Element("eventid").Value;
this.txtBox1.Text = id.FirstOrDefault();
}
}
}
but it worked perfectly fine with normal xml file below
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Customers>
<Customer ID="101">
<Name>Robert</Name>
<Mobile>9820098200</Mobile>
<Location>Bangladesh</Location>
<Address>XYZ</Address>
</Customer>
<Customer ID="102">
<Name>Kate</Name>
<Mobile>983452342</Mobile>
<Location>Japan</Location>
<Address>ABC</Address>
</Customer>
<Customer ID="103">
<Name>Catherine</Name>
<Mobile>123456785</Mobile>
<Location> London</Location>
<Address>CDE</Address>
</Customer>
<Customer ID="10004">
<Name>Richard</Name>
<Mobile>899990012</Mobile>
<Location>France</Location>
<Address>MNO</Address>
</Customer>
</Customers>
I believe that's because you are using strings to refer to element. You should use XName, e.g. instead of "Events" or "eventid" use:
var events = XName.Get("Events", "http://www.aab.org/logevents");
var eventId = XName.Get("eventid", "http://www.aab.org/logevents");
You can use below powershell snippet for a quick test:
$x = [System.Xml.Linq.XDocument]::Load("C:\Users\Jack\source\repos\xmltest\Xmltest\XmlFile.xml")
$evtName = [System.Xml.Linq.XName]::Get("Events", "http://www.aab.org/logevents")
$idName = [System.Xml.Linq.XName]::Get("eventid", "http://www.aab.org/logevents")
$x.Descendants($evtName).Element($idName).Value | Write-Host
You have to handle the Xml Namespace. You can do this by querying with XName, instead of with a string:
using System;
using System.Linq;
using System.Xml.Linq;
public class Program
{
public static void Main()
{
var inXml = #"<soapenv:Envelope xmlns:soapenv=""http://www.w3.org/2001/12/soap-envelope"" soapenv:encodingStyle=""http://www.w3.org/2001/12/soap-encoding"" >
<soapenv:Body xmlns:lle=""http://www.aab.org/logevents"" >
<lle:Events>
<lle:eventid>ID1</lle:eventid>
<lle:tweet>
<lle:text>This is some tweet in my day</lle:text>
<lle:location>
<lle:lat>66</lle:lat>
<lle:long>77</lle:long>
</lle:location>
<lle:datetimestamp>datetimestamp</lle:datetimestamp>
</lle:tweet>
</lle:Events>
</soapenv:Body>
</soapenv:Envelope>";
var eventIdsXName = XName.Get("eventid", "http://www.aab.org/logevents");
var eventIds = XDocument.Parse(inXml)
.Descendants(eventIdsXName)
.Select(i => i.Value);
foreach(var eventId in eventIds){
Console.WriteLine($"Value: {eventId}");
}
}
}
Output:
Value: ID1
See:
https://dotnetfiddle.net/IEdwz1

get decendents in XML where specific element contains value

<?xml version="1.0" encoding="utf-8" ?>
<Licenses>
<License>
<LicenseType>Temporary License</LicenseType>
<BundleType>Line</BundleType>
<Features>
<Feature>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
<Feature>
<Name>EnhancedUserAccounts</Name>
<LocalisedName>Enhanced User Accounts</LocalisedName>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
</Features>
</License>
<License>
<LicenseType>Temporary License</LicenseType>
<BundleType>Line</BundleType>
<Features>
<Feature>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
<Feature>
<Name>EnhancedUserAccounts</Name>
<LocalisedName>Enhanced User Accounts</LocalisedName>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
</Features>
</License>
</Licenses>
How to read the feature list into to IEnumerable if my BundleType = line
You can do this easily using XDocument
var xDocument = XDocument.Parse(XML)
or
var xDocument = XDocuemnt.Load(FilePath)
then:
xDocument.Descendants("LicenseType")
Which will get all nodes that descend from LicenseType
To test for that BundleType element you could do something like:
nodes.Where(n=>n.Element("BundleType") == "Line").Decesendants("Features")
which will get all Features where <BundleType> of the parent is "Line"
EDIT: As per comments, to get all features:
xDocument.Desecendants("Features")
That will get all <Feature> nodes under the <Features> Element
Use following based on the xml I updated on your posting :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication70
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("License").Where(x => (string)x.Element("BundleType") == "Line")
.Select(x => x.Descendants("Feature").ToList()).ToList();
}
}
}

XML C# Parse - Complex

I have been on google for a while but am just stumped. I need to parse xml of this nature. I can't seem to skip to elements in the middle, e.g. Folder. I have limited the xml as there were many 'Folder' elements. Any guidance would be appreciated. I was after the FolderID element's attribute ID.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="14"
MinorVersion="1"
MajorBuildNumber="225"
MinorBuildNumber="46"
Version="Exchange2010_SP1"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="AAMkADk5MmY1ZThmLTM2MzAtNGVh" ChangeKey="AQAAABYAAACSe/NBrSZiQKqHx8yL+lIRAAAA1EWM" />
<t:ParentFolderId Id="AAMkADk5MmY1ZThmLTM2MzAtNGVh" ChangeKey="AQAAAA==" />
<t:DisplayName>Top of Information Store</t:DisplayName>
<t:TotalCount>0</t:TotalCount>
<t:ChildFolderCount>15</t:ChildFolderCount>
<t:EffectiveRights>
<t:CreateAssociated>true</t:CreateAssociated>
<t:CreateContents>true</t:CreateContents>
<t:CreateHierarchy>true</t:CreateHierarchy>
<t:Delete>true</t:Delete>
<t:Modify>true</t:Modify>
<t:Read>true</t:Read>
<t:ViewPrivateItems>true</t:ViewPrivateItems>
</t:EffectiveRights>
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet>
<t:UnreadCount>0</t:UnreadCount>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
LINQ to XML is the best .NET XML Parsing API.
See
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/xdocument-class-overview
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace ConsoleApp12
{
class Program
{
static void Main(string[] args)
{
var doc = XDocument.Load(#"c:\temp\foo.xml");
var ns = (XNamespace)"http://schemas.microsoft.com/exchange/services/2006/types";
var folders = doc.Descendants(ns + "Folder");
foreach (var e in folders)
{
var folderId = e.Element(ns + "FolderId").Attribute("Id").Value;
Console.WriteLine(folderId);
}
Console.WriteLine("Hit any key to exit.");
Console.ReadKey();
}
}
}
You should learn about serlialization. It's very easy to convert an XML to and from a object in C#. https://www.codeproject.com/Articles/483055/XML-Serialization-and-Deserialization-Part
That said, this will get you the data you're after. It's not very reusable and won't help you with any xml files other than ones with one instance of that attribute, but it's what you're after so here you go.
string FolderId;
string ChangeKey;
using (StreamReader sr = new StreamReader("c:\\myfile.xml"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("<t:FolderId Id="))
{
try
{
var lineArray = line.Split('\"');
FolderId = lineArray[1];
ChangeKey = lineArray[3];
}
catch
{
// handle exception
}
}
}
}
You can use the XSD.exe to create a schema class. and then using XML deserializer, you can deserialize/parse xml to object
Using xml linq
XDocument doc = XDocument.Load(FILENAME);
List<XElement> folders = doc.Descendants().Where(x => x.Name.LocalName == "Folder").ToList();
XNamespace tNs = folders.FirstOrDefault().GetNamespaceOfPrefix("t");
XElement id_AAMkADk5MmY1ZThmLTM2MzAtNGVh = folders.Where(x => (string)x.Element(tNs + "FolderId").Attribute("Id") == "AAMkADk5MmY1ZThmLTM2MzAtNGVh").FirstOrDefault();

How to fetch specific data from XML using C#

I'm trying to fetch specific data from a Xml file to display in a textbox. My Xml file name as "test.xml" has following code
<?xml version="1.0" encoding="utf-8" ?>
<Body>
<Context>
<PageNo>a87</PageNo>
<Verse>"Do it right"</Verse>
</Context>
</Body>
My C# code is below: Edited to reflect recent chnages
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace learn2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pageid1();
}
private void pageid1()
{
textBox1.Clear();
XmlDocument doc = new XmlDocument();
doc.Load("C:\\test.xml");
var pagenoNodeList = doc.SelectNodes("Body/Context/PageNo");
var pageNoNode = pagenoNodeList[0]; // To select the first node
var text = pageNoNode.InnerText; // Gets the text value inside the node
textBox1.Text = text;
} }
}
I highly appreciate any help. Thanks
You need to identify the node you are looking for, as SelectNodes returns a System.Xml.XmlNodeList, and then get the value of InnerText:
var pagenoNodeList = doc.SelectNodes("Body/Context/PageNo");
var pageNoNode = pagenoNodeList[0]; // To select the first node
var text = pageNoNode.InnerText; // Gets the text value inside the node
textBox1.Text = text;

Unable to Parse XMl after unwrapping soap body

I have been trying hard to parse an xml string, but all to no avail
<EnquirySingleItemResponse xmlns="http://tempuri.org/"> <EnquirySingleItemResult>
<Response>
<MSG>SUCCESS</MSG>
<INFO>TESTING</INFO>
</Response> </EnquirySingleItemResult> </EnquirySingleItemResponse>
My Code returns null or the texts in the xml tags no matter how i parse it. I have checked some post, but they seem not to be working.
See my code snipped below
XElement anotherUnwrappedResponse = ( from _xml in axdoc.Descendants(tempuri + "EnquirySingleItemResponse")
select _xml).FirstOrDefault();
string response = anotherUnwrappedResponse.Value;
axdoc.Descendants is used because i unwrapped the soap body, to have the xml above
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<EnquirySingleItemResponse xmlns=\"http://tempuri.org/\">" +
"<EnquirySingleItemResult>" +
"<Response>" +
"<MSG>SUCCESS</MSG>" +
"<INFO>TESTING</INFO>" +
"</Response> </EnquirySingleItemResult> </EnquirySingleItemResponse>";
XDocument doc = XDocument.Parse(input);
string msg = doc.Descendants().Where(x => x.Name.LocalName == "MSG").FirstOrDefault().Value;
string info = doc.Descendants().Where(x => x.Name.LocalName == "INFO").FirstOrDefault().Value;
}
}
}
​

Categories