XML to list using LINQ - c#

have an XML file like this:
<VS>
<Fields>
<Field Id="$1*">Column1</Field>
<Field Id="$2*">Column2</Field>
<Field Id="$3*">Column3</Field>
</Fields>
</VS>
When I use LINQ to XML using the following statement:
XDocument doc = XDocument.Parse(s);
var q = doc.Descendants("Fields").ToList();
I get a single entry in list as Column1Column2Column3, whereas I want it as 3 separate entities like Column1, Column2, Column3.
Can anyone help?

Use Field instead of Fields:
var q = doc.Descendants("Field").ToList();

you should use XElement.Parse(BuildNode.InnerXml) instead of just passing the raw property in.
Check This

Just used the following code which returned list of strings.
var q = doc.Descendants("Field").Select(x => x.Value);
Thanks for all your suggestions!

Related

c# LINQ get Attribute value from XElement

I have the below XML in a data definitions file:
<PQTemplate documentID="CSTrlsEN" documentType="TransList" templateID="001"
templateType="Customer Copy"
templateName="C:\CPS\_templates\Mini-Statements\CSTrlsEN.doc">
<field pos="5" name="YPTME" descr="Time" />
<field pos="6" name="YPDTE" descr="Action Date" />
<field pos="7" name="YPBRNO" descr="Branch Number" />
<field pos="8" name="YPBNA" descr="Branch Name" />
<field pos="9" name="YPTID" descr="Teller ID" />
<field pos="10" name="YPISN" descr="Teller Sequence" />
<field pos="11" name="YPREF" descr="Customer Reference" />
<field pos="12" name="YPCUS" descr="Customer Name" />
<field pos="13" name="YPEAN" descr="Account Number" />
<field pos="14" name="YPATY" descr="Account Type" />
<field pos="15" name="YPCUR" descr="Currency" />
<field pos="16" name="YPBAL" descr="Available Balance" />
I get that specific XElement using LINQ, extracting it from an XML file that contains several PQTemplate elements by using the below LINQ Expression:
var mapInfo = from nm in XElement.Elements("PQTemplate")
where (string)nm.Attribute("documentID") == sRequests[0].Split('\t')[0]
select nm;
Now I need to get the value of the attribute documentType so I tried the below LINQ Expression:
var repName = from d in mapInfo.Attributes("documentType")
select d.Value;
reportName = repName.ToString();
Unfortunately although I can see the value TransList is part of the reportName element, I have had no luck trying to retrieve it.
Here is an image showing it in VS 2013:
so how can I get the documentType attribute in the element?
That's because repName will return an IEnumerable<string> for all the mapInfo.
IEnumerable<string> repName = from d in mapInfo.Attributes("documentType")
select d.Value;
So either use a foreach loop if you suspect you may get more values or use First to get first attribute like this:-
string reportName = mapInfo.First().Attribute("documentType").Value;
Linq queries return collections. Do for each over repName or
repName.First().ToString()
if that is all you need.
Your solution depends on how many elements DocumentType exist in your XML. If it´s only one (what I suppose) you may use repName.First().ToString().
If the attribute may occure more than once you should use a loop instead:
var result = new List<string>();
foreach(var a in (from d in mapInfo.Attributes("documentType") select d.Value)
result.Add(a.ToString());
Or even shorter:
result = mapInfo.Attributes("documentType").Select(x => x.Value.ToString());
Which will return an enumeration.
Change
var mapInfo = from nm in XElement.Elements("PQTemplate")
where (string)nm.Attribute("documentID") == sRequests[0].Split('\t')[0]
select nm;
to
var mapInfo = from nm in XElement.Elements("PQTemplate")
where (string)nm.Attribute("documentID") == sRequests[0].Split('\t')[0]
select nm.Attribute("documentType").Value;
then mapInfo.First() will give you the value you want.
To get a single value out of a LINQ query you have to call for example First or FirstOrDefault. If you call FirstOrDefault it won't throw an exception if the query returns no matches.
string repName = doc.Elements("PQTemplate")
.Where(e => (string)a.Attribute("documentID") == sRequests[0].Split('\t')[0])
.Select(e => (string)e.Attribute("documentType"))
.FirstOrDefault();
Also, you don't need to call ToString() on XAttribute.Value as it's already a string.

Data retrieving from XElemnt using LINQ

I have an XElement as follows
<row>
<field name="field1">Test1</field>
<field name="field2">Test2</field>
<field name="field3">Test3</field>
</row>
I want to retrieve value Test2 using the attribute value field2 using LINQ.I tried the following code
var data= item.Elements("field").Single(x => x.Attribute("name").Value == "field2");
It's not working.When I run the code it fails with error Sequence contains no matching element >
I don't know what I'm missing here.How can I retrieve the value using LINQ
I found the mistake. The code should be like this
var data = item.Elements().Single(x => x.Attribute("name").Value == "field2").Value;

How to retrieve attribute from xml

I have the following xml in XmlDocument. I am trying to extract the className from it.
<Registration className="Eng" type="DirectRegistration" state="Activated" xmlns="http://xyz/Registration">
<Fields>
<Field type="abc" value="123456" />
<Field type="xyz" value="789" />
</Fields>
</Registration>
I have tried the following code but its not giving me className.
var xmlNode = xmlDoc.DocumentElement;
Can anyone help me to get the value of className out.
Many Thanks
You were almost there:
var className = xmlDoc.DocumentElement.GetAttribute("className");
xmlDoc.DocumentElement gives you the whole element; GetAttribute pulls an individual named attribute from it.
Try using this:
// Trying to parse the given file path to an XML
XmlReader firstXML = XmlReader.Create(XMLPath);
firstXML.ReadToFollowing("Registration");
firstXML.MoveToAttribute("className");
var res = firstXML.Value;
res will hold "className" value.
you can also use xPath to retrieve the attribute
string className = xmlDocument.SelectSingleNode("//Registration/#className").Value;

Reading elements into a dictionary object using LINQ

I am using traditional XmlReader to parse a xml document into a dictionary? However i am in search for less complicated method minimum lines of code. I have the following Xml document
<Msg>
<field id="0" value="0100"/>
<field id="3" value="310000"/>
<field id="7" value="0101150110"/>
<field id="11" value="000002"/>
</Msg>
Is it possible to split the following xml document into a dictionary object with key being the attribute and value being the value of that element?
eg:-
Key = 0 value =0100
Rather than using XmlReader, I'd suggest using LINQ to XML, at which point it's really simple:
var dictionary = document.Descendants("field")
.ToDictionary(x => (int) x.Attribute("id"),
x => (string) x.Attribute("value"));
var query = (from element in document.Descendants("field"))
.ToDictionary(pair => (int)pair.Attribute("id"),
pair => (string)pair.Attribute("value"));

linq to xml access data based on field attribute

I have some xml like this:
<Data>
<Rows>
<Row>
<Field Name="title">Mr</Field>
<Field Name="surname">Doe</Field>
<Row>
<Rows>
<Data>
using linq how can I get the value contained in the field element where the attribute is surname
thanks
Here is how you can express your query using LINQ to XML:
XDocument doc = XDocument.Parse("<Data><Rows><Row><Field Name=\"title\">Mr</Field><Field Name=\"surname\">Doe</Field></Row></Rows></Data>");
string[] matches = (from e in doc.Descendants("Field")
where (string)e.Attribute("Name") == "surname"
select (string)e).ToArray();
Actually, you're trying to do an XML-to-Linq thing here. Linq to XML is more meant to create an XML structure from objects through Linq.
Since you have an XML file, you can use something like this:
XmlDocument xml = new XmlDocument();
xml.LoadXml(Content);
string Surname = xml.SelectSingleNode("//Field/[#Name='surname']").Value.ToString();
In other use, to get data from XML, use XPath instead.

Categories