How to get all descendants with a particular attribute - Linq to Xml - c#

<Grid>
<StringColumn Header="Name"/>
<DateColumn Header="Date"/>
</Grid>
There is probably an existing answer to this question, but I cannot seem to find it.
I need to find all xml elements which have an attribute of "Header"
The name of the element can be different.
How do I do that with Linq to XML?

This should give you the required elements:
XDocument document = ...;
var elementsWithHeader = document.Descendants()
.Where(e => e.Attributes().Any(a => a.Name == "Header"));

Something like this should work:
IEnumerable<XElement> elements =
from el in root.Elements("Grid")
where (string) el.Attribute("Header") != null
select el;

Use this:
var grid = XElement.Parse(#"<Grid>
<StringColumn Header=""Name""/>
<DateColumn Header=""Date""/>
</Grid>");
var elements = grid.XPathSelectElements(".//*[#Header]");

Using xml linq. Code is prints any Grid elements that have children with Header attributes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication7
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> headers = doc.Descendants("Grid").Where(x => x.Elements().Where(y => y.Attribute("Header") != null).Any()).ToList();
}
}
}

Related

Finding Specific xml nodes using XDocument

I am trying to find specific nodes in xml using XDocument. The xml also has a namespace which am importing.
Below is the xml specs
<?xml version="1.0" encoding="UTF-8"?>
<tns:response xmlns:tns="http://amazon.com/amazonservices">
<tns:responseDirect>
<tns:responseExtract>
<tns:A>ExtractName</tns:A>
</tns:responseExtract>
<tns:responses>
<tns:Name>Response1</tns:Name>
<tns:Include>No</tns:Include>
</tns:responses>
<tns:responses>
<tns:Name>Response2</tns:Name>
<tns:Include>Yes</tns:Include>
</tns:responses>
<tns:responses>
<tns:Name>Response3</tns:Name>
</tns:responses>
</tns:responseDirect>
I want to retrieve all responses and also only those nodes which have Include nodes present.
I am trying below code to fetch it but I am getting none of the nodes.
XDocument document = XDocument.Parse(xml);
var name = from nm in document.Elements("responses")
select nm;
Can anyone let me know how to fix the issue?I need to only fetch the response node.
Thanks in Advance
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns = doc.Root.GetNamespaceOfPrefix("tns");
var results = doc.Descendants(ns + "responses")
.Where(x => x.Elements(ns + "Include").Any())
.Select(x => new {
include = (string)x.Element(ns + "Include"),
name = (string)x.Element(ns + "Name")
}).ToList();
}
}
}

C# How to read an value from xml tag (xmlnodelist) using their attribute?

Could you helping me to know how get the value of xml tag using their attribute with C#.
need:
Code example
<Friend>
<FName>Patrick</FName>
<LName>Aston</LName>
<Age>22</Age>
<FriendsIdList>
<FriendId IdType="school">29982252</FriendId>
<FriendId IdType="athome">2334568</FriendId>
<FriendId IdType="atcamp">9908787</FriendId>
<FriendId IdType="studygroup">6588432</FriendId>
</FriendsIdList>
</Friend>
How to get the value of tag <FriendId IdType="XXXXX">XXXXXX</FriendId> I was try using XMLnodelist into an foreach sequence, but without success.
Do you have any suggestion?
Thanks for your help.
Try xml linq using a dictionary to get Ids
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication51
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("Friend").Select(x => new {
fName = (string)x.Element("FName"),
lName = (string)x.Element("LName"),
age = (int)x.Element("Age"),
ids = x.Descendants("FriendId")
.GroupBy(y => (string)y.Attribute("IdType"), z => (string)z)
.ToDictionary(y => y.Key, z => z.FirstOrDefault())
}).ToList();
}
}
}

Deserialize XML containing a Dictionary

I have an XML file containing identifiers that I would like Get, the xml look like
<Dictionary
x:TypeArguments="x:String, x:Object"
xmlns="clr-namespace:System.Collections.Generic;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<List x:TypeArguments="x:Int32" x:Key="key" Capacity="4">
<x:Int32>60371408</x:Int32>
<x:Int32>60371409</x:Int32>
</List>
</Dictionary>
The identifiers that I want to get is 60371408, 60371409
I just found a solution :
Thank you for your reaction :D
Create an XmlSerializer:
var serializer = new XmlSerializer(typeof(Dictionary<string, object>));
...then deserialize. You haven't specified what form this XML is in, whether you have a string or a stream, for example. Here's how you'd deserialize an XML string:
var reader = new StringReader(xml);
var dict = serializer.Deserialize(reader);
Now you have your Dictionary<string, object>, but since values are plain objects, you'll need to cast the values:
var list = (List<int>)dict["key"];
Try xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
public class Program
{
const string FILENAME = #"c:\temp\test.xml";
public static void Main()
{
XDocument doc = XDocument.Load(FILENAME);
XElement dictionary = doc.Descendants().Where(x => x.Name.LocalName == "Dictionary").FirstOrDefault();
XNamespace xNs = dictionary.GetNamespaceOfPrefix("x");
var results = dictionary.Descendants(xNs + "Int32").Select(x => (int)x).ToList();
}
}
}

Linq to XML select node from config.xml (Lambda expression or classic query)

I am using .net 4.0 winforms. In my application a have config file (config.xml), on this file i have lots nodes and child nodes, all are different, i want to select specific node and nodes inside the selected node.
I tried lots of solutions but not succeed.
Thanks in advance for your help.
This should give you the correct result:-
XDocument doc = XDocument.Load(#"XMLFilePath");
XNamespace ns = "http://schemas.datacontract.org/2004/07/Silvio.Settings";
var result = doc.Root.Element(ns + "maintenance_anomalies")
.Descendants(ns + "nom_operation")
.Select(x =>
new
{
NomOperation = (string)x,
statutList = x.Parent.Element(ns + "statuts")
.Elements(ns + "statut")
.Select(z => (string)z).ToList()
}).ToList();
Approach:
From the Xdocument object select the root node which is Main. From this select the Element maintenance_anomalies by including the Namespace associated with it. From there you can select all the descendants of nom_operation and fetch it's value. To find all statut inside nom_operation go back to parent node which is operation and from there select all statut elements.
You can also project a Type instead of anonymous type.
Getting following output:-
I had a couple of issues with your xml. First there is an invalid character so instead of using the Load method. There is also a namespace issue so I used Where method to get the tag maintenance_anomalies.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication53
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string file = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(file);
XElement maintenance_anomalies = doc.Descendants().Where(x => x.Name.LocalName == "maintenance_anomalies").FirstOrDefault();
XNamespace ns = maintenance_anomalies.Name.Namespace;
var results = maintenance_anomalies.Elements(ns + "operation").Select(x => new{
nom_operation = x.Element(ns + "nom_operation").Value,
statut = string.Join(",",x.Descendants(ns + "statut").Select(y => y.Value).ToArray())
}).ToList();
}
}
}
The line below should let u access the node u requested. Use this is your class using System.Xml;
XmlDocument XmlDocObj = new XmlDocument();
XmlNode UserNameNode = XmlDocObj.SelectSingleNode("maintenance_anomalies");

Read XML with ab:tag format using c#

I am new to xml, c#. I am following this tutorial: http://www.dotnetcurry.com/ShowArticle.aspx?ID=564
But my xml file is little different. The xml that I want to read in my c# code is this: http://api.nextag.com/buyer/synd.jsp?search=ipod&ver=15&token=AQB7dB$kB8ULvbGT&pid=1807
Code I am trying to read this xml is:
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)
{
XElement xelement = XElement.Load("http://api.nextag.com/buyer/synd.jsp?search=ipod&ver=15&token=AQB7dB$kB8ULvbGT&pid=1807");
XNamespace nxtg = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2011-01-11T08:31:30";
IEnumerable<XElement> employees = xelement.Elements();
// Read the entire XML
foreach (var employee in employees)
{
//Console.WriteLine(employee);
//Console.WriteLine(employee.Value);
if (employee.Element(nxtg + "search-category") == null)
continue;
else
Console.WriteLine(employee.Element(nxtg + "search-category").Value);
//Console.WriteLine(employee.Element("EmpId").Value);
}
But no luck. Anyone can help me please.
xelement.Elements() will return direct children of root element. In your case that will be elements nxtg:publisher, nxtg:search-query, nxtg:search-category etc. Thus nxtg:search-category is a direct child of root element, it also will selected as employee. That's why you can't find it in children of employee. You should do following instead:
// keep in mind, you have incorrect namespace value
XNamespace nxtg = "http://namespace.nextag.com/business-objects";
var searchCategory = xelement.Element(nxtg + "search-category");
var node = searchCategory.Element(nxtg + "node");
var displayName = (string)node.Element(nxtg + "display-name");
var value = (int)node.Element(nxtg + "value");

Categories

Resources