C# XML linq query - c#

Hi I have the following XML:
<EPICORTLOG>
<POS>
<ClientId>WkStn.90.1</ClientId>
<Id>POS.90.20140819.251.8279</Id>
<StartTime>2014-08-25T05:12:34</StartTime>
<Store>90</Store>
<SysDate>2014-08-19T00:00:00</SysDate>
<TillNo>1</TillNo>
<Time>2014-08-25T05:12:34</Time>
<Tran>1093</Tran>
<WkStn>1</WkStn>
<WORKSTATION>
<IsAutoLock>1</IsAutoLock>
</WORKSTATION>
<TRADE>
<ITEM>
<Class>102499</Class>
<Desc>NIKE RACER</Desc>
<FinalPrice>82.77</FinalPrice>
<Status>ACTV</Status>
<Style>EV0615</Style>
<Tag>1</Tag>
</ITEM>
</TRADE>
</POS>
</EPICORTLOG>
There are many POS nodes like above in the actual XML. I am trying to fetch the POS node with ID=POS.90.20140819.251.8279 and then the details of Item from that particular node. I have written the following query:
XDocument xdoc = XDocument.Load(XMLFile);
var item = from items in xdoc.Element("EPICORTLOG").Descendants("POS")
where items.Attribute("Id").Value == strSelectedPOSID
select new
{
desc=items.Element("ITEM").Attribute("Desc")
};
But it is not yielding any result for me. Here strSelectedPOSID=POS.90.20140819.251.8279. Please let me know where i am going wrong.

Id and Desc are not an Attributes. they are Elements so you should use
var item = from items in xdoc.Descendants("POS")
where (string)items.Element("Id") == strSelectedPOSID
select new
{
desc = (string)items.Element("ITEM").Element("Desc")
};

I got the value at last!! Following is what i used:
var item = from items in xdoc.Element("EPICORTLOG").Descendants("POS")
where (string)items.Element("Id") == strSelectedPOSID
select new
{
desc = items.Element("TRADE").Element("ITEM").Element("Desc").Value.ToString()
};
Thanks for the inputs.

Related

XML to List in C#

This is the xml:
<Packages>
<Package>
<Id>1</Id>
<Prerequisites>
<Prerequisite>7</Prerequisite>
<Prerequisite>8</Prerequisite>
</Prerequisites>
</Package>
<Package>
<Id>2</Id>
.....
</Package>
....
</Packages>
And the list:
class lista
{
public int id {get; set;}
public List<int> pre{get;set;}
}
How can I add This xml pattern to a list of lista class and this is what i have got so far bot it only put one in the second list.
XDocument xdoc = XDocument.Load("Employee.xml");
var ListPckage =
(from item in xdoc.Descendants("Package")
orderby item.Element("Id").Value
select new
{
Id = item.Element("Id").Value,
Prerequisite = item.Element("Prerequisites").Element("Prerequisite").Value,
}).ToList();
foreach works for shoing them
foreach (var item in ListPckage)
{
Console.WriteLine(item.Id);
foreach (var item1 in ListPckage)
{
Console.WriteLine(item1.Prerequisites);
}
}
As John Sket mentioned in the comment to the question, one way to achieve that is to use Linq To Xml.
//string xcontent = #"xml content here";
//XDocument xdoc = XDocument.Parse(xcontent);
XDocument xdoc = XDocument.Load("FullPathToXml");
List<lista> resultlist = xdoc.Descendants("Package")
.Select(x=> new lista
{
id = Convert.ToInt32(x.Element("Id").Value),
pre = x.Descendants("Prerequisite").Select(y=>Convert.ToInt32(y.Value)).ToList()
})
.ToList();
But, i'd suggest to use XmlSerialization/XmlDeserialization.
First parse the XML to XDocument using XDocument.Parse to get XML in XDocument variable i.e.
var requiredXml = XDocument.Parse("Xml String here")
Then you can use LINQ to Xml (something like) as below:
//may be syntactic error but you can get an idea
var requiredList =
from element in requiredXml.Descandants("Package")
Select new lista { id = element.Element("ID").Value,
pre = element.Elements("Prerequisite").Select(x=> Convert.ToInt32(x.Value)).ToList() }

C# Read a specific element which is in a XML Node

I searched a long time in order to get an answer but as i can see is not working.
I have an XML File and I would like to read a specific element from a node.
For example, this is the XML:
<Root>
<TV>
<ID>2</ID>
<Company>Samsung</Company>
<Series>13523dffvc</Series>
<Dimesions>108</Dimesions>
<Type>LED</Type>
<SmartTV>Yes</SmartTV>
<OS>WebOS</OS>
<Price>1993</Price>
</TV>
</Root>
I want to get the ID element in the code as a variable so i can increment it for the next item which i will add.
This is the code at this moment, but i can not find a way to select something from the item itself.
XDocument doc = XDocument.Load("C:TVList.XML");
XElement TV = doc.Root;
var lastElement = TV.Elements("TV").Last()
A query for the last TV's id (this will return 0 if there are no elements):
var lastId = (int) doc.Descendants("TV")
.Elements("ID")
.LastOrDefault();
You might also want the highest id (in case they're not in order):
var maxId = doc.Descendants("TV")
.Select(x => (int)x.Element("ID"))
.DefaultIfEmpty(0)
.Max();
See this fiddle for a working demo.
Use like this to get id value
XDocument doc = XDocument.Load(#"C:\TVList.XML");
XElement root = doc.Element("Root");
XElement tv = root.Element("TV");
XElement id = tv.Element("ID");
string idvalue = id.Value;
also make your <Type>LED</Tip> tag of xml to <Type>LED</Type> for match

how to print the innertext of an element based on attribute search of a particular node using LINQ?

**I have an XML like this-
<?xml version="1.0" encoding="UTF-8"?>
<Tool_Parent>
<tool name="ABCD" id="226">
<category>Centralized</category>
<extension_id>0</extension_id>
<uses_ids>16824943 16824944</uses_ids>
</tool>
<tool name="EFGH" id="228">
<category>Automated</category>
<extension_id>0</extension_id>
<uses_ids>92440 16824</uses_ids>
</tool>
</Tool_Parent>
Based on the id of tool i want to print the uses_ids value,i.e if i search for 228 i should get 92440 16824.
I had tried like-
var toolData = (from toolElement in doc.Descendants("tool")
select new Tool_poco
{
a_Name = tool.Attribute("name").Value,
a_Id = tool.Attribute("id").Value,
e_ExtensionId = tool.Element("extension_id").Value,
e_UsesIds =tool.Element("uses_parm_ids").Value
});
where Tool_poco is a poco class for tool node containing declaration for member variable.
Now I want to get information related to a particular tool id in toolData variable.How to do it?
Note: I have variable like-
searched_Tool_id = Tool_Id_txtBx.Text.ToString();
Please let me know a way through which i can modify my above query for toolData.**
You can modify your query as
Tool_poco toolData = (from el in xelement.Elements("Employee")
where (string)el.Attribute("id") == "226"
select new Tool_poco
{
a_Name = el.Attribute("name").Value,
a_Id = el.Attribute("id").Value,
e_ExtensionId = el.Element("Name").Value,
e_UsesIds = el.Element("uses_ids").Value
}).FirstOrDefault();
You could start by doing something like this once you have an XDocument object loaded and ready:
var xdoc = XDocument.Parse(
#"<?xml version=""1.0"" encoding=""utf-8""?>
<Tool_Parent>
<tool name=""ABCD"" id=""226"">
<category>Centralized</category>
<extension_id>0</extension_id>
<uses_ids>16824943 16824944</uses_ids>
</tool>
<tool name=""EFGH"" id=""228"">
<category>Automated</category>
<extension_id>0</extension_id>
<uses_ids>92440 16824</uses_ids>
</tool>
</Tool_Parent>");
var root = xdoc.Root; // Got to have that root
if (root != null)
{
var id228query = (from toolElement in root.Elements("tool")
where toolElement.HasAttributes
where toolElement.Attribute("id").Value.Equals("228")
let xElement = toolElement.Element("uses_ids")
where xElement != null
select xElement.Value).FirstOrDefault();
Console.WriteLine(id228query);
Console.Read();
}
Output: 92440 16824
**Note: In reference to your example, one possible reason it was not working
for you could be that your xml references an element with name "uses_ids",
however, your query references an element with a similar, but not exact,
spelling with name "uses_parm_ids".**

Extracting XML values from two nodes

I want to extract the value in the moduleId attibute and the value from the Field node. For example, in this first node I want to extract the 447 in the moduleId and the 124694 from the Field node. I have the XML loaded in an XDocument. The end result will be a Tuple where the first item is the value from the moduleId attribute and the second item is the value from the Field node. Is there a way I can do this using one XLinq statement?
As a bonus...I only want to do it for nodes where the guid = "07a188d3-3f8c-4832-8118-f3353cdd1b73". This part I can probably figure out if someone can tell me how to extract information from two nodes, but a bonus would be to add the WHERE clause in there for me :)
<Records>
<Record moduleId="447">
<Field guid="07a188d3-3f8c-4832-8118-f3353cdd1b73">124694</Field>
</Record>
<Record moduleId="447">
<Field guid="07a188d3-3f8c-4832-8118-f3353cdd1b73">124699</Field>
</Record>
<Records>
I have gotten as far as extracting the Field value using this...
IEnumerable<string> c = from p in sourceDocument.Descendants("Field")
where p.Attribute("guid").Value == "07a188d3-3f8c-4832-8118-f3353cdd1b73"
select p.Value;
But I have no idea how to get information from both the Record node and the Field node.
Give this a try:
var doc = XDocument.Parse(xml);
var r = doc.Descendants("Record")
.Where(n => n.Element("Field").Attribute("guid").Value == "07a188d3-3f8c-4832-8118-f3353cdd1b73")
.Select(n => new { ModuleId = n.Attribute("moduleId").Value, Field = n.Element("Field").Value });
var a = r.ToArray();
Here is a solution that uses LINQ Query Syntax:
XDocument document = XDocument.Parse(xml);
var query =
from el in document.Root.Elements("Record")
where (string)el.Element("Field").Attribute("guid") ==
"07a188d3-3f8c-4832-8118-f3353cdd1b73"
select new
{
ModuleId = (string)el.Attribute("moduleId"),
Field = (string)el.Element("Field")
};
foreach (var item in query)
{
Console.WriteLine
("ModuleId:[{0}]\nField:[{1}]\n--",
item.ModuleId,
item.Field);
}

simple way to read xml data using linq

I have a xml structure like this. Can anyone help with a simple linq function to read this xml structure.The itemEntry node repeats according to data. I tried to read the xml using the method below,but i am getting no records in the list. Is this method here correct way to get the details...
List<CX_ITEMLIST> sList =
(from e in XDocument.Load(param.FileName).Root.Elements("itemEntry")
select new CX_ITEMLIST
{
TITLE = (string)e.Element("title"),
YEAR = (string)e.Element("year"),
ITEMNAME = (string)e.Element("itemname"),
CATRYLIST =
(
from p in e.Elements("categorylist").Elements("categories")
select new CATLIST
{
IDTYPE = (string)p.Element("categoryid"),
IDNUMBER = (string)p.Element("categoryName")
}).ToList()
}).ToList();
<itemslist>
<itemInformation>
<itemdate>01/23/2014</itemdate>
<itemcount>57</itemcount>
</itemInformation>
<itemEntry>
<title>Title1</title>
<year>2013</title>
<itemname>testname</itemname>
<categorylist>
<categories>
<categoryid>Category1</categoryid>
<categoryName>Category2</categoryName>
</categories>
<categories>
<categoryid>Category1</categoryid>
<categoryName>Category2</categoryName>
</categories>
</categorylist>
</itemEntry>
<itemEntry>
<title>Title1</title>
<year>2013</title>
<itemname>testname</itemname>
<categorylist>
<categories>
<categoryid>Category1</categoryid>
<categoryName>Category2</categoryName>
</categories>
<categories>
<categoryid>Category1</categoryid>
<categoryName>Category2</categoryName>
</categories>
</categorylist>
</itemEntry>
</itemslist>
You should try with XDocument.
XDocument xdoc = XDocument.Load("file.xml");
The System.Xml.XLinq namespace contains some awesome objects to make this easy.
var xDoc = XDocument.Parse(xml); // load your xml string, or use XDocument.Load() to load an xml file
var itemEntries = xDoc
.Root // refers to itemEntries node
.Descendants("itemEntry"); // gets all itemEntry nodes in an IEnumerable object
This gets you an IEnumerable<XNode> of all the itemEntry nodes.
From there you can do what you need, save the values to a business object, etc.
The above method works properly, i found the issue, my xml tag was having namespace attribute. i tried to get the namespace and append it with Elements while reading
XNamespace ns = xDocument.Root.Attribute("xmlns").Value;
List<CX_ITEMLIST> sList =
(from e in XDocument.Load(param.FileName).Root.Elements(ns + "itemEntry")
select new CX_ITEMLIST
{
TITLE = (string)e.Element(ns + "title"),
YEAR = (string)e.Element(ns + "year"),
ITEMNAME = (string)e.Element(ns + "itemname"),
CATRYLIST =
(
from p in e.Elements(ns + "categorylist").Elements(ns + "categories")
select new CATLIST
{
IDTYPE = (string)p.Element(ns + "categoryid"),
IDNUMBER = (string)p.Element(ns + "categoryName")
}).ToList()
}).ToList();

Categories

Resources