I'm trying to write a query for an Xml file.
this is my input Xml file :
<logentry
revision="10034">
<date>2009-10-07T03:45:38.000000Z</date>
<paths>
<path
kind="file"
action="M">/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java</path>
<path
kind="file"
action="M">/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/core/BugzillaRepositoryConnectorStandaloneTest.java</path>
</paths>
</logentry>
I'm trying to filter all the log between date 2006-05-01 and 2007-09-01. and my output it should be like this:
10034 2009-10-07 BugzillaRepositoryConnectorTest.java,BugzillaRepositoryConnectorStandaloneTest.java
it means for each specific revision number where is between date1 and date2 I want to have list of all files from tag . I used regular expression for separating the file name from the path.
this is my code:
using(System.IO.StreamWriter file1= new System.IO.StreamWriter( #"/home/datehistory"))
{XDocument log= XDocument.Load(#"/home/output.xml");
var selected= from logs in log.Descendants("logentry")
select new
{revno=logs.Attribute("revision").Value,
date=logs.Element("date").Value,
list1= {from files in logs.Element("paths").Element("path").Value
let match=Regex.Match(files,#"/([A-Za-z0-9\-]+.java)<",RegexOptions.IgnoreCase);
where match.Success
select new
{filename=match.Groups[1].Value }; }
???? "please help " where date between 2006-05-01 and 2007-09-01
};
foreach (var d in selected)
{
file1.Write(d.revno);
file1.Write("\t");
file1.Write(d.date);
file1.Write("\t");
foreach item in d.list1
{file1.write(item);
file1.write("\t"); }
file1.write("\n");
}
Have you considered a simpler approach? For example something like this:
var xml =
#"<logentry
revision='10034'>
<date>2009-10-07T03:45:38.000000Z</date>
<paths>
<path
kind='file'
action='M'>/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java</path>
<path
kind='file'
action='M'>/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/core/BugzillaRepositoryConnectorStandaloneTest.java</path>
</paths>
</logentry>";
XDocument log= XDocument.Parse(xml);
foreach (var entry in log.Descendants("logentry")) {
var date = DateTime.Parse(entry.Element("date").Value);
Console.WriteLine(date);
foreach (var path in entry.Descendants("path")) {
var idx = path.Value.LastIndexOf('/');
Console.Write(path.Value.Substring(idx + 1) + ", ");
}
Console.WriteLine();
}
}
This leaves a trailing ", " but it's just an example instead of writelines you could add the info to a struct or container and output it to a file like your original example.
Try this:
using System;
using System.IO;
using System.Xml.Linq;
using System.Linq;
using System.Text;
class Program
{
static void Main(string[] args)
{
var outputPath = "outputPath.log";
var xDoc = XDocument.Load("input.xml");
var sb = new StringBuilder();
xDoc.Descendants("logentry").Cast<XElement>()
.Where(e =>
{
var date = DateTime.Parse(e.Descendants("date")
.FirstOrDefault().Value);
return date >= new DateTime(2006, 5, 1) &&
date <= new DateTime(2007, 9, 1);
}).ToList().ForEach(e =>
{
var revision = e.Attribute("revision").Value;
var date = DateTime.Parse(e.Descendants("date")
.FirstOrDefault().Value).ToString("yyyy-MM-dd");
sb.Append(String.Format("{0}\t", revision));
sb.Append(String.Format("{0}\t", date));
e.Descendants("path")
.Where(p => Path.GetExtension(p.Value).ToLower() == ".java")
.ToList().ForEach(p =>
sb.Append(String.Format("{0},",
Path.GetFileName(p.Value))));
if (sb[sb.Length - 1] == ',')
sb.Length = sb.Length - 1;
sb.AppendLine();
});
File.WriteAllText(outputPath, sb.ToString());
}
}
Related
I am new to C# coding and I have really tried to find an answer in any forum. I am using CSVHelper to read a CSV file and I want to skip a certain number of lines from the beginning of the file to a certain word. Now my code gives the following error message:
System.ObjectDisposedException: "Cannot read from a closed TextReader." Help me please :
private void cmdLoad_Click(object sender, EventArgs e)
{
OpenFileDialog OFDReader = new OpenFileDialog()
{ };
if (OFDReader.ShowDialog() == DialogResult.OK)
{
txtbox.Text = OFDReader.FileName;
}
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ";", // Set delimiter
HasHeaderRecord = true,
//ShouldSkipRecord = (row) => row.Record[0].Contains("Date/Time"),
};
using (var reader = new StreamReader(OFDReader.FileName))
using (var csv = new CsvReader(reader, config))
{
//search for Line to start reader
string record = "Date/Time";
while (csv.Read())
{
if (csv.Read().Equals(record))
{
csv.Read();
csv.ReadHeader();
break;
}
using (var dr = new CsvDataReader(csv))
{
var dt = new DataTable();
dt.Load(dr);
dataGridView1.DataSource = dt; // Set datagridview source to datatable
}
}
}
}
}
}
I believe you just need to break out of the while (csv.Read()) when you find the "Date/Time" text. The CsvReader will do the rest from there.
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ";", // Set delimiter
HasHeaderRecord = true
};
using (var reader = new StreamReader(OFDReader.FileName))
using (var csv = new CsvReader(reader, config))
{
//search for Line to start reader
string record = "Date/Time";
while (csv.Read())
{
if (csv.Context.Parser.RawRecord.Trim() == record)
{
break;
}
}
using (var dr = new CsvDataReader(csv))
{
var dt = new DataTable();
dt.Load(dr);
dt.Dump();
}
}
I have the following in my xml:
<mur>
<bak>
</bak>
<itemfb ident="c_fb">
<flow_m>
<mat>
<text texttype="text/plain">correct answer comments</text>
</mat>
</flow_m>
</itemfb>
<itemfb ident="gc_fb">
<flow_m>
<mat>
<text texttype="text/plain">wrong, you made a blunder</text>
</mat>
</flow_m>
</itemfb>
</mur>
Now, the 'itemfb' tag, may or may not exist within a 'mur' tag and if exists, I need to parse and get the values "correct answer comments" (or) "wrong, you made a blunder" depending on "itemfb" ident. Here is what I have tried. Assume rowObj has the loaded xml from "mur" and 'ns' is the namespace
if (rowObj.Elements(ns + "itemfb").Any())
{
var correctfb = (from cfb in rowObj
.Descendants(ns + "itemfb")
where (string)cfb.Attribute(ns + "ident").Value == "cfb"
select new
{
ilcfb = (string)cfb.Element(ns + "mat")
}).Single();
some_variable_1 = correctfb.ilcfb;
var incorrectfb = (from icfb in rowObj
.Descendants(ns + "itemfb")
where (string)icfb.Attribute(ns + "ident").Value == "gcfb"
select new
{
ilicfb = (string)icfb.Element(ns + "mat")
}).Single();
some_variable_2 = incorrectfb.ilicfb;
}
This should be a way to get the information you want. I omitted ns for simplicity.
var correctfb = rowObj.Descendants("mur")
.Descendants("itemfb")
.Where(e => e.Attribute("ident").Value == "c_fb")
.Descendants("text").FirstOrDefault();
if (correctfb != null)
some_variable_1 = correctfb.Value;
var incorrectfb = rowObj.Descendants("mur")
.Descendants("itemfb")
.Where(e => e.Attribute("ident").Value == "gc_fb")
.Descendants("text").FirstOrDefault();
if (incorrectfb != null)
some_variable_2 = incorrectfb.Value;
How to parser this xml content.
<Content>
<caption> Today Headline </caption>
<s1>
<name>6</name>
<name>4</name>
<name>4</name>
</s1>
<s2>
<name>3</name>
<name>6</name>
<name>0</name>
</s2>
</Content>
Mycode:
date = (from story
in xmlParser.Descendants("s1")
select new EspnViewModel
{
Category = story.Element("name").Value,
}).ToList();
return data;
I'm having a hard time trying to figure out how to parse everything out.
Why dont you use xmlParser.Descendants("name") instead?
EDIT:
var caption = xmlParser.Descendants("caption").First().InnerText;
var names = from story in xmlParser.Descendants("name")
select new EspnViewModel
{
Category = story.InnerText
}).ToList();
Note: I am writing this in haste, but you get the idea..
private List<yourclass> ReadList()
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists("xmlName.xml"))
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("xmlName.xml", FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<your class>));
List<yourclass> data = (List<yourclass>)serializer.Deserialize(stream);
return data.ToList();
}
}
else
{
return null;
}
}
}
I got the code for the Table in the powerpoint using the code generator, but I am not able to add the table to an existing powerpoint document.
I tried adding another table to the intended slide and doing the following:
Table table = slidePart.Slide.Descendants<Table>().First();
table.RemoveAllChildren();
Table createdTable = CreateTable();
foreach (OpenXmlElement childElement in createdTable.ChildElements)
{
table.AppendChild(childElement.CloneNode(true));
}
But that didn't work.
I am out of ideas on this issue.
My original target is to add a table with dynamic number of columns and fixed number of row to my presentation.
I know its been very long since this question is posted, but just in case if some one needs a working code to create table in pptx.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using A = DocumentFormat.OpenXml.Drawing;
using System.IO;
namespace ANF.Slides.TestEngine
{
class Program
{
static int index = 1;
static void Main(string[] args)
{
Console.WriteLine("Preparing Presentation");
PopulateData();
// GeneratedClass cls=new GeneratedClass();
//cls.CreatePackage(#"E:\output.pptx");
Console.WriteLine("Completed Presentation");
Console.ReadLine();
}
private static void PopulateData()
{
var overflow = false;
const int pageBorder = 3000000;
var db = new AdventureWorksEntities();
var products = db.Products;//.Take(5);
const string outputFile = #"E:\openxml\output.pptx";
File.Copy(#"E:\OpenXml\Template.pptx", outputFile, true);
using (var myPres = PresentationDocument.Open(outputFile, true))
{
var presPart = myPres.PresentationPart;
var slideIdList = presPart.Presentation.SlideIdList;
var list = slideIdList.ChildElements
.Cast<SlideId>()
.Select(x => presPart.GetPartById(x.RelationshipId))
.Cast<SlidePart>();
var tableSlidePart = (SlidePart)list.Last();
var current = tableSlidePart;
long totalHeight = 0;
foreach (var product in products)
{
if (overflow)
{
var newTablePart = CloneSlidePart(presPart, tableSlidePart);
current = newTablePart;
overflow = false;
totalHeight = 0;
}
var tbl = current.Slide.Descendants<A.Table>().First();
var tr = new A.TableRow();
tr.Height = 200000;
tr.Append(CreateTextCell(product.Name));
tr.Append(CreateTextCell(product.ProductNumber));
tr.Append(CreateTextCell(product.Size));
tr.Append(CreateTextCell(String.Format("{0:00}", product.ListPrice)));
tr.Append(CreateTextCell(product.SellStartDate.ToShortDateString()));
tbl.Append(tr);
totalHeight += tr.Height;
if (totalHeight > pageBorder)
overflow = true;
}
}
}
static SlidePart CloneSlidePart(PresentationPart presentationPart, SlidePart slideTemplate)
{
//Create a new slide part in the presentation
SlidePart newSlidePart = presentationPart.AddNewPart<SlidePart>("newSlide" + index);
index++;
//Add the slide template content into the new slide
newSlidePart.FeedData(slideTemplate.GetStream(FileMode.Open));
//make sure the new slide references the proper slide layout
newSlidePart.AddPart(slideTemplate.SlideLayoutPart);
//Get the list of slide ids
SlideIdList slideIdList = presentationPart.Presentation.SlideIdList;
//Figure out where to add the next slide (find max slide)
uint maxSlideId = 1;
SlideId prevSlideId = null;
foreach (SlideId slideId in slideIdList.ChildElements)
{
if (slideId.Id > maxSlideId)
{
maxSlideId = slideId.Id;
prevSlideId = slideId;
}
}
maxSlideId++;
//Add new slide at the end of the deck
SlideId newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);
//Make sure id and relid is set appropriately
newSlideId.Id = maxSlideId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(newSlidePart);
return newSlidePart;
}
private static A.TableCell CreateTextCell(string text)
{
var textCol = new string[2];
if (!string.IsNullOrEmpty(text))
{
if (text.Length > 25)
{
textCol[0] = text.Substring(0, 25);
textCol[1] = text.Substring(26);
}
else
{
textCol[0] = text;
}
}
else
{
textCol[0] = string.Empty;
}
A.TableCell tableCell3 = new A.TableCell();
A.TextBody textBody3 = new A.TextBody();
A.BodyProperties bodyProperties3 = new A.BodyProperties();
A.ListStyle listStyle3 = new A.ListStyle();
textBody3.Append(bodyProperties3);
textBody3.Append(listStyle3);
var nonNull = textCol.Where(t => !string.IsNullOrEmpty(t)).ToList();
foreach (var textVal in nonNull)
{
//if (!string.IsNullOrEmpty(textVal))
//{
A.Paragraph paragraph3 = new A.Paragraph();
A.Run run2 = new A.Run();
A.RunProperties runProperties2 = new A.RunProperties() { Language = "en-US", Dirty = false, SmartTagClean = false };
A.Text text2 = new A.Text();
text2.Text = textVal;
run2.Append(runProperties2);
run2.Append(text2);
paragraph3.Append(run2);
textBody3.Append(paragraph3);
//}
}
A.TableCellProperties tableCellProperties3 = new A.TableCellProperties();
tableCell3.Append(textBody3);
tableCell3.Append(tableCellProperties3);
//var tc = new A.TableCell(
// new A.TextBody(
// new A.BodyProperties(),
// new A.Paragraph(
// new A.Run(
// new A.Text(text)))),
// new A.TableCellProperties());
//return tc;
return tableCell3;
}
}
}
I need to select distinct rows from Textfile display below.
TextFile
123| one| two| three <br/>
124| one| two| four <br/>
125| one |two| three <br/>
Output should like this
123| one| two| three <br/>
124| one| two| four <br/>
OR
124| one| two| four <br/>
125| one |two| three <br/>
I am using this code to work out this problem
var readfile = File.ReadAllLines(" text file location ");
var spiltfile = (from f in readfile
let line = f.Split('|')
let y = line.Skip(1)
select (from str in y
select str).FirstOrDefault()).Distinct()
Thanks
The unclear spacing in the question doesn't help (especially around the |two|, which has different spacing than the rest, implying we need to use trimming), but here's some custom LINQ methods that do the job. I've used the anon-type purely as a simple way of flattening out the inconsistent spacing (I could also have rebuilt a string, but it seemed unnecessary)
Note that without the odd spacing, this can be simply:
var qry = ReadLines("foo.txt")
.DistinctBy(line => line.Substring(line.IndexOf('|')));
Full code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
static class Program
{
static void Main()
{
var qry = (from line in ReadLines("foo.txt")
let parts = line.Split('|')
select new
{
Line = line,
Key = new
{
A = parts[1].Trim(),
B = parts[2].Trim(),
C = parts[3].Trim()
}
}).DistinctBy(row => row.Key)
.Select(row => row.Line);
foreach (var line in qry)
{
Console.WriteLine(line);
}
}
static IEnumerable<TSource> DistinctBy<TSource, TValue>(
this IEnumerable<TSource> source,
Func<TSource, TValue> selector)
{
var found = new HashSet<TValue>();
foreach (var item in source)
{
if (found.Add(selector(item))) yield return item;
}
}
static IEnumerable<string> ReadLines(string path)
{
using (var reader = File.OpenText(path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
}
Check out this, this will do what you want to do
static void Main(string[] args)
{
string[] readfile = System.IO.File.ReadAllLines(#"D:\1.txt");
var strList = readfile.Select(x => x.Split('|')).ToList();
IEnumerable<string[]> noduplicates =strList.Distinct(new StringComparer());
foreach (var res in noduplicates)
Console.WriteLine(res[0] + "|" + res[1] + "|" + res[2] + "|" + res[3]);
}
And implement the IEqualityComparer this way
class StringComparer : IEqualityComparer<string[]>
{
public bool Equals(string[] x, string[] y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x[1].Trim() == y[1].Trim() && x[2].Trim() == y[2].Trim() && x[3].Trim() == y[3].Trim() ;
}
public int GetHashCode(string[] data)
{
if (Object.ReferenceEquals(data, null)) return 0;
int hash1 = data[1] == null ? 0 : data[1].Trim().GetHashCode();
int hash2 = data[2] == null ? 0 : data[2].Trim().GetHashCode();
int hash3 = data[3] == null ? 0 : data[3].Trim().GetHashCode();
return hash1 ^ hash2 * hash3;
}
}
It will give u the output as you expected.