Querying XML elements with identical name with Linq - c#

I have the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<ProductTypes>
<ProductType Name="MyProduct">
<Amount>100</Amount>
<Pattern Length="1" AllowedCharacters="ABCD"/>
<Pattern Length="7" AllowedCharacters="EFGH"/>
</ProductType>
</ProductTypes>
Using Linq to XML I can successfully extract information from any number of the element ProductType. However I also need the information from all of the elements Pattern.
XElement xml = XElement.Load("pattern_config.xml");
var productTypes = from productType in xml.Elements("ProductType")
select new {
Name = productType.Attribute("Name").Value,
Amount = Convert.ToInt32(productType.Element("Amount").Value)
// How to get all Pattern elements from that ProductType?
};
How can I do this? Or would you recommend another way accessing this XML?

You can nest queries.
var productTypes = from productType in xml.Elements("ProductType")
select new {
Name = productType.Attribute("Name").Value,
Amount = Convert.ToInt32(productType.Element("Amount").Value),
// How to get all Pattern elements from that ProductType?
Patterns = from patt in productType.Elements("Pattern")
select new { Length = int.Parse(patt.Attribute("Length").Value),
.... }
};

Related

How to read data from xml of specific format

I want to read xml as below using linq. I want to read all elements and their sub elements and values to use in to my code. For example I want to read ParameterID2, and its child elements and display those.
<?xml version="1.0" encoding="utf-8"?>
<labelled>
<historyRecord recordedtime="12/12/1906">
<ParameterID2>
<parameterName>SWVersion</parameterName>
<engineeringUnit>###</engineeringUnit>
<previousValue>R1.2.3</previousValue>
</ParameterID2>
<ParameterID3>
<parameterName>SWVersion</parameterName>
<engineeringUnit>###</engineeringUnit>
<previousValue>R1.2.3</previousValue>
</ParameterID3>
<ParameterID4>
<parameterName>SWVersion</parameterName>
<engineeringUnit>###</engineeringUnit>
<previousValue>R1.2.3</previousValue>
</ParameterID4>
<ParameterID5>
<parameterName>SWVersion</parameterName>
<engineeringUnit>###</engineeringUnit>
<previousValue>R1.2.3</previousValue>
</ParameterID5>
</historyRecord>
</labelled>
I tried as code given below.
string xmlDocPath = "C:\\Users\\Dipak\\Desktop\\Documentation.xml";
string timestamp = "12/12/1906"; // this can vary
XDocument xmlDdoc = XDocument.Load(xmlDocPath);
var selectRecord = from recordS in xmlDdoc.Descendants("historyRecord").Where
(recordS => (string)recordS.Attribute("recordedtime") == timestamp)
select new
{
parameterID1 = recordS.Element("ParameterID2").Name,
// parameterID2 = recordS.Element("ParameterID3"),
parameterName = recordS.Element("parameterName").Value,
engineeringUnit = recordS.Element("engineeringUnit").Value,
previousValue = recordS.Element("previousValue").Value,
};

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".**

C# XML linq query

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.

Retrieving Multiple Items from an XML File using LINQ to XML with C#

I'm new to LINQ to XML and I'm having problems writing C# to retrieve multiple items from an XML file, i.e. in the code sample below. I would like to go through the file and retrieve each OrderProduct id=??? and get the information in Quantities and Product. I can retrieve a single order only, but not if more than one is in the file.
This is the C# code I'm using which only retrieves the first order.
xelement = XElement.Load (orderXML);
IEnumerable<XElement> OrderXml = xelement.Elements ();
foreach (var order in OrderXml.Elements ("OrderProducts"))
{
m_productOrderID = order.Element ("OrderProduct").Attribute ("id").Value;
m_productName = order.Element ("OrderProduct").Element ("Product").Element ("Name").Value;
m_productCatalogNumber = order.Element ("OrderProduct").Element ("Product").Element ("CatalogNumber").Value;
m_productQuantity = order.Element ("OrderProduct").Element ("Quantities").Element ("NumberOfCopies").Value;
}
The XML file:
<?xml version="1.0" encoding="utf-16"?>
<OrderXml>
<Order>
<OrderProducts>
<OrderProduct id="569">
<Quantities>
<NumberOfRecipients>1</NumberOfRecipients>
<NumberOfCopies>1</NumberOfCopies>
<TotalUnits>1</TotalUnits>
</Quantities>
<Product id="444">
<Name>Product 1</Name>
<CatalogNumber>20130621-001</CatalogNumber>
</Product>
</OrderProduct>
<OrderProduct id="570">
<Quantities>
<NumberOfRecipients>1</NumberOfRecipients>
<NumberOfCopies>100</NumberOfCopies>
<TotalUnits>100</TotalUnits>
</Quantities>
<Product id="258">
<Name>Product 2</Name>
<CatalogNumber>20130621-002</CatalogNumber>
</Product>
</OrderProduct>
</OrderProducts>
</Order>
</OrderXml>
from op in xdoc.Descendants("OrderProduct")
let q = op.Element("Quantities")
let p = op.Element("Product")
select new {
Id = (int)op.Attribute("id"),
Quantities = new {
NumberOfRecipients = (int)q.Element("NumberOfRecipients"),
NumberOfCopies = (int)q.Element("NumberOfCopies"),
TotalUnits = (int)q.Element("TotalUnits")
},
Product = new {
Id = (int)p.Attribute("id"),
Name = (string)p.Element("Name"),
CatalogNumber = (string)p.Element("CatalogNumber")
}
}
Then getting single order product:
var orderProduct = query.FirstOrDefault(x => x.Id == yourId);
if (orderProduct != null)
// ...
Getting all ids:
var ids = xdoc.Descendants("OrderProduct")
.Select(op => (int)op.Attribute("id"));
BTW Next time provide code which you already have

LINQ to XML via C#

I'm new to LINQ. I understand it's purpose. But I can't quite figure it out. I have an XML set that looks like the following:
<Results>
<Result>
<ID>1</ID>
<Name>John Smith</Name>
<EmailAddress>john#example.com</EmailAddress>
</Result>
<Result>
<ID>2</ID>
<Name>Bill Young</Name>
<EmailAddress>bill#example.com</EmailAddress>
</Result>
</Results>
I have loaded this XML into an XDocument as such:
string xmlText = GetXML();
XDocument xml = XDocument.Parse(xmlText);
Now, I'm trying to get the results into POCO format. In an effort to do this, I'm currently using:
var objects = from results in xml.Descendants("Results")
select new Results
// I'm stuck
How do I get a collection of Result elements via LINQ? I'm particularly confused about navigating the XML structure at this point in my code.
Thank you!
This will return a IEnumerable of anonymous class:
var q = from result in xml.Descendants
select new
{
ID = result.Descendants("ID"),
Name= result.Descendants("Name"),
EmailAddress= result.Descendants("EmailAddress")
};
or if you have defined class `Result, e.g.:
class Result
{
public ID { get; set; }
public Name { get; set; }
public EmailAddress { get; set; }
}
then:
var q = from result in xml.Descendants
select new Result
{
ID = result.Descendants("ID"),
Name = result.Descendants("Name"),
EmailAddress = result.Descendants("EmailAddress")
};
(returns IEnumerable<Result>)
If your Results child elements are only Result elements, then you can get them like this:
var objects = from result in xml.Descendants
select result;
But in this lucky case you can just use xml.Descendants.
If it's not only Result elements, then this will do fine:
var object = from result in xml.Descendants
where result.Name == "Result"
select result;

Categories

Resources