Accessing Linq to XML query results with [] in C# - c#

In this post, the Linq to XML query result are accessed with iterator as follows.
foreach (var elem in elems) {
var res = elem.Elements("ClassKeyName");
foreach (var e in res) {
Console.WriteLine(e.Value);
}
}
Can I access the result with []? For example, I want to use as follows,
foreach (var elem in elems) {
var res = elem.Elements("ClassKeyName");
Console.WriteLine(res[0].Value);
}
However, I got this error message
xmlparse.cs(18,34): error CS0021:
Cannot apply indexing with [] to an expression of type
`System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>'

You'd just have to convert the results to an indexable type, such as a list:
foreach (var elem in elems) {
List<XElement> res = elem.Elements("ClassKeyName").ToList();
Console.WriteLine(res[0].Value);
}
(You can still use var if you want - I've just given it an explicit type to make it clearer in this case.)

If you only need the first, you can res.First().Value. If you need the n-th element res.Skip(n - 1).Value (so the first element is res.Skip(0).Value, the second res.Skip(1).Value...).
The big question is WHY? What do you want to do?

Related

IEnumerable<> being skipped by foreach code; Converting IEnumerable<> to List<> doesnt return anything

Basically I have this code:
public static async Task<bool> SubmitOrdertoBroker(CASOrderModel order, IEnumerable<CASOrderItemModel> modelOrderItems)
{
ObservableCollection<CASOrderItem> casOrderItemModel = new ObservableCollection<CASOrderItem>();
var i = (from m in modelOrderItems select m).ToList();
foreach (dynamic item in modelOrderItems)
{
CASOrderItem orderItem;
orderItem = new CASOrderItem();
orderItem.Createdby = item.Createdby;
orderItem.CreatedDate = item.CreatedDate;
orderItem.ItemMetaPK = item.ItemMetaPK;
orderItem.OrderItem = item.OrderItem;
orderItem.OrderItemID = item.OrderItemID;
orderItem.ParentOrderID = item.ParentOrderID;
orderItem.PrdMainPK = item.PrdMainPK;
orderItem.Quantity = item.Quantity;
orderItem.TacticPkey = item.TacticPkey;
casOrderItemModel.Add(orderItem);
}
return true;
}
The issues are:
1.) The foreach {} block is not iterating, and it just skips the code (even if modelOrderItems has 4 items in it), thereby rendering my casOrderItemModel empty (which I am passing to another code block after this code that supposedly populates the collection).
2.) If I try to convert the IEnumerable to a List, the list doesn't contain any items.
Please let me know how I can fix this issue.
Thank you. :)
Your function takes a parameter IEnumerable<CASOrderItemModel> modelOrderItems on which you call ToList():
var i = (from m in modelOrderItems select m).ToList();
But then you iterate over modelOrderItems, not over i:
foreach (dynamic item in modelOrderItems) { ... }
Evaluating the same enumerable collection twice can result in the second iteration being empty, depending on the source of your collection. Try doing this and remove the unused ToList() line:
foreach (CASOrderItemModel item in modelOrderItems) { ... }
Or if you really want to have that explicit ToList() in there:
foreach (var item in i) { ... }
Finally, since your collection contains a strong typed item CASOrderItemModel, using dynamic makes no sense.
Try changing your IEnumerable<T> with List<T>. My assumption here is that since it is an interface, there has to be an object that holds your list anywhere in the application.

Efficiently join XML to a collection, and then perform an update to the XML

Can anyone please help me out with the lambda expression for fetching the value for which i used foreach loop?
foreach (var keysValue in configParameters)
{
foreach (XmlNode childNode in node.ChildNodes)
{
if (childNode.Attributes["key"].Value == keysValue.Key)
{
childNode.Attributes["value"].Value = keysValue.Value;
}
}
}
Since i have not exposed to lamba expression, i am asking you all. kindly help me out in learning also.
var updateInfos =
from XmlNode childNode in node.ChildNodes
let key = childNode.Attributes["key"].Value
join keysValue in configParameters on key equals keysValue.Key
select new { childNode, keysValue.Value };
That efficiently joins the two collections. Now we update:
foreach (var updateInfo in updateInfos)
updateInfo.childNode.Attributes["value"].Value = updateInfo.Value;
We do as much as possible in the functional LINQ query. Then we update using foreach. It is useful to separate queries and mutations as much as possible. Use LINQ for the query part, use foreach for mutations.

Retrieving hierarchy using ADOMD and not MDX query

I want to retrieve hierarchy from one of the cube. I want to form a JSON structure so I am hoping if I can use ADOMD and use a recursive function to get this information and show the result in TreePanel.
I need to form JSON from the output.
foreach (var att in dimension.Hierarchies)
{
foreach (var m in att.Levels[1].GetMembers())
{
var path = att.UniqueName;
}
}
The above code only gets me level 1 attributes. I don't know how to get all the child attributes for given attribute.
Please help
To modify your original code to loop all the levels (instead of just level 1) is simple, but I'm guessing you are after the names of the members within each level.
Your original line var path = att.UniqueName; will return the same value many times over, won't it?
foreach (var att in dimension.Hierarchies)
{
foreach (var lev in att.Levels) //NEW LOOP
{
foreach (var m in lev.GetMembers())
{
var membername = m.UniqueName; //GET VALUE HERE
}
}
}
Where I have used UniqueName you could use any member property - read about ADOMD to find out what is available.

Access Attributes of object inside a dictionary

I am working on a winforms application using C#. I have a dictionary with specific objects, the object have attributes Id and DocType. How can i access the attributes of every object in a foreach statement. i Am trying with the following code but is not working. Any help pls?
foreach (var doc in crs.DocDictionary)
{
Console.WriteLine( doc.Id);
Console.WriteLine(doc.docType);
}
If you foreach on a dictionary you get a sequence of KeyValuePair<TKey,TValue>; try:
foreach (var doc in crs.DocDictionary.Values)
{
Console.WriteLine(doc.Id);
Console.WriteLine(doc.docType);
}
or:
foreach (var pair in crs.DocDictionary)
{
Console.WriteLine(pair.Key);
Console.WriteLine(pair.Value.Id);
Console.WriteLine(pair.Value.docType);
}

linq looping through tags with the same name

I'm some what new to linq could uses some help..
I have an xml file that looks like this:
<InputPath>
<path isRename="Off" isRouter="Off" pattern="pattern-1">d:\temp1</path>
<path isRename="Off" isRouter="pattern-1">d:\temp2</path>
</InputPath>
I need to loop through and get the key values of the tag "path".
What I have so far is
var results = from c in rootElement.Descendants("InputPath") select c;
foreach (XElement _path in results)
{
string value = _path.Element("path").Value;
}
But I only get the last <path> value. Any help would be great.
Have you tried just just enumerating the path items?
foreach (var element in rootElement.Descendants("path"))
{
var value = element.Value;
}
You'll only get the first element that way, because that's what the Element method gives you: the first child element with the given name.
If you want multiple elements you can just use Elements instead:
// Note: the query expression here is pointless.
var results = from c in rootElement.Descendants("InputPath") select c;
foreach (XElement _path in results)
{
string value = _path.Elements("path").Value;
// Use value here...
}
Alternatively, use the Elements extension method and do it all in one go:
foreach (var path in rootElement.Descendants("InputPath").Elements("path"))
{
string value = path.Value;
// Use value here
}
If that doesn't help, please give more information about what you're trying to do and what the problem is.
If by "last" you mean "the element contents" that's because you're using the Value property. If you want the attributes within the path element, you need the Attribute method, as shown by IamStalker, although personally I'd usually cast the XAttribute to string (or whatever) rather than using the Value property, in case the attribute is missing. (It depends on what you want the behaviour to be in that case.)
What you need is, to loop through the attributes like so
foreach (XElement xElem in rootElement.Descendants("InputPath"))
{
string isRename = xElem.Attribute("isRename").Value;
}

Categories

Resources