I have XML Document like
<Records>
<Record>
<Event>Home Value Submits Page 2</Event>
<Date>17-Mar-14 4:49:32 PM</Date>
</Record>
<Record>
<Event>Hm Value Submits Hm Pg</Event>
<Date>17-Mar-14 4:54:36 PM</Date>
</Record>
</Records>
I need to delete last 30 Days nodes from XML Document.
I am using this code but it's not working,
var xelement = XElement.Load(Server.MapPath("~/XMLStorage/DataBase.xml"));
var value30days =
from nm in xelement.Elements("Record")
where (DateTime)nm.Element("Date") <= DateTime.Now && (DateTime)nm.Element("Date") >= DateTime.Now.AddDays(-30)
select nm;
foreach (XElement xEle in value30days)
{
xEle.Remove();
}
xelement.Save(Server.MapPath("~/XMLStorage/DataBase.xml"));
Please Give some solutions.
This is one of those fun problems caused by changing a collection while enumerating/querying it. As soon as you try to remove the first item you break the query.
Try this:
foreach (XElement xEle in value30days.ToArray())
{
xEle.Remove();
}
The ToArray call will ensure that the entire set of results is returned before you start modifying the XML content. You can then iterate through the array and delete as many of those items as you like without the loop breaking.
Related
Hello i am trying to get simple xml file from server and to read the data so i can convert it to list. I was try few lib and code with no success so far. I am getting the xml content in one line without any tags <> and the count is always 0 zero. The XML string. I need to get the data that inside camp tag
<campaigns>
<mainPage>http://example.com</mainPage>
<orderPage>https://www.example.co.il/adver/</orderPage>
<totalCount>3</totalCount>
<onLineCount>2</onLineCount>
<campaignList>
<camp id="557">
<name>test1</name>
<status>on</status>
<rating>5</rating>
<url>http://example.com/557</url>
</camp>
<camp id="559">
<name>test1</name>
<status>on</status>
<rating>5</rating>
<url>http://example.com/559</url>
</camp>
<camp id="660">
<name>test1</name>
<status>off</status>
<rating>5</rating>
<url>http://example.com/660</url>
</camp>
</campaignList>
And the c# code i am trying so far
XElement xelement = XElement.Load("http://example.com/test.xml");
var name = from nm in xelement.Elements("camp")
where (string)nm.Element("status") == "on"
select nm;
Response.Write(name.Count());
foreach (XElement xEle in name)
{
Response.Write(xEle);
}
XElement.Elements() means search in children tags. I think what you need is Descendants() or xelement.Element("campaigns").Element("campaignList").Elements("camp")
When I run the following code and step through it with a break point and look at temp I see "Empty, Enumeration yielded no results" and the MessageBox.Show never fires. I'm trying to pull everything under Season no="1"
XElement sitemap = XElement.Load(#"http://services.tvrage.com/feeds/episode_list.php?sid=" + this.showID);
IEnumerable<XElement> temp = from el in sitemap.Elements("Season")
where (string)el.Attribute("no") == "1"
select el;
foreach (XElement el in temp)
{
MessageBox.Show("found something");
}
This is the XML that's being loaded:
http://services.tvrage.com/feeds/episode_list.php?sid=6312
You're looking for elements called Season directly under the root element... whereas your XML looks like this:
<Show>
<name>The X-Files</name>
<totalseasons>9</totalseasons>
<Episodelist>
<Season no="1">
<episode>
...
If you want to look for all descendant elements with a given name, use Descendants instead of Elements. That certainly finds elements in the example XML you've given.
I have an XML document which I load from the disk
XDocument events = XDocument.Load("Content/GameData/events.xml");
The contents of this xml are the following:
<?xml version='1.0' encoding='UTF-8'?>
<Events>
<level1>
<NarrationEvent code="lvl1_fridge">
I can't even remember when I last ate.
I am not hungry though.
</NarrationEvent>
<NarrationEvent code="lvl1_tv">
Why do I even have a TV?
Oh right, I use it as a screen for my laptop.
</NarrationEvent>
<NarrationEvent code="lvl1_bed">
Oh man, I am beat.
</NarrationEvent>
<NarrationEvent code="lvl1_computer">
Oh, look at that. The project has been compiled.
</NarrationEvent>
</level1>
<level2>
</level2>
<level3>
</level3>
<level4>
</level4>
<cave>
</cave>
</Events>
I use this code here supposedly select the appropriate NarrationEvent element, based on its attribute "code"
IEnumerable<XElement> v =
(from narrationEvent in events.Elements("NarrationEvent")
where (string)narrationEvent.Attribute("code") == code
select narrationEvent);
foreach (XElement page in v)
{
//Console.WriteLine("ff");
narration.Add(page.Value);
}
This returns nothing, my XElement Ienumerable is empty. I used breakpoints and the code value is passed to this method just fine. e.g. "lvl1_bed"
What is wrong with this code?
You can use the Descendants-Method to get your NarrationEvent-Element. I have updated your code accordingly.
IEnumerable<XElement> v = from narrationEvent in events.Descendants("NarrationEvent")
where narrationEvent.Attribute("code").Value == code
select narrationEvent;
I have a xml document that has a record set like this.
<document>
<row>
<Pub_Code>OHB-A0011</Pub_Code>
<Sec>16</Sec>
<Pags>20</Pags>
<Copies>1,000</Copies>
<Binding>Saddle Stitch</Binding>
<Tab>No tabs</Tab>
<Qty>0</Qty>
<Cover>Self Cover</Cover>
<Tpgs>0</Tpgs>
</row>
</document>
I have a linq query wrtten this way:
string xml_path = #"D:\Server-Apps\BooksData.xml";
XElement root = XElement.Load(xml_path);
var selected = from myBooks in root.Elements("row") where myBooks.Element("Pub_Code").Value == "OHB-A0011" select myBooks;
foreach (var d in selected)
{
Console.WriteLine("Pub_Code: {0}", d.Element("Pub_Code").Value);
Console.WriteLine("Cover: {0}", d.Element("Cover").Value);
d.SetElementValue("Tpgs", "test");
}
I can read the value find but when I uses d.SetElementValue("Tpgs", "test"); nothing gets update.
the tag is already in the xml file .
If you want to save the updated XML back to the file, you need to do:
root.Save(xml_path);
I added the line t the end of your program and it seems to work correctly.
I'm trying to populate an array with the following xml:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<data>
<item>
<date>1307018090</date>
<price>10.4718867</price>
<low>10.38100000</low>
<high>10.49000000</high>
<nicedate>14:39</nicedate>
</item>
<item>
...
</item>
and so on
I'm using this Linq-query, which to me means that It'll create one object per :
var items = from item in doc.Element("data").Descendants()
select new Currency
{
Close = item.Element("price").Value.ToString(),
Date = item.Element("date").Value.ToString(),
Low = item.Element("low").Value.ToString(),
High = item.Element("high").Value.ToString(),
Time = item.Element("nicedate").Value.ToString()
};
And when I foreach through items, only one item gets selected. I'm not very used to Linq so I can't figure out how to properly construct this statement. Any suggestions?
You need to start the Linq-Xml like so
var items =
from item in
doc.Element("data")
.Elements("item")
Descedants() method returns not only children, but also grand-children, grand-grand-children etc. So, the second tag that gets processed by LINQ is your first <item>'s <date> and it isn't processed (I think there should be an exception here, can't check at the moment).
Replace your Descedants() call to Elements("item"), as suggested by #DaveShaw