Hello. Implemented the conversion as follows:

using System.Xml.Linq; XElement xmlf = new XElement("Folder", new XElement("name", "NASI PARTNERZY HANDLOWI"), from str in source let fields = str.Split(';') select new XElement("Placemark", new XElement("name", fields[0]), new XElement("description", fields[1]), new XElement("styleUrl", fields[2]), new XElement("ExtendedData", new XElement("Data", new XAttribute("name", "opis"), new XElement("value", fields[3])), new XElement("Data", new XAttribute("name", "Informacje:"), new XElement("value", fields[4])), new XElement("Data", new XAttribute("name", "Telefon:"), new XElement("value", fields[5])), new XElement("Data", new XAttribute("name", "E-mail"), new XElement("value", fields[6])), new XElement("Data", new XAttribute("name", "Strona:"), new XElement("value", fields[7])), new XElement("Data", new XAttribute("name", "gx_media_links"), new XElement("value", fields[8]))), new XElement("Point", new XElement("coordinates", fields[9])))); 

In the end, I get the right structure, but filled with incorrect data. Example structure:

  <Folder> <name>Company</name> <Placemark> <name>Company name</name> <description>Some description</description> <styleUrl>#icon-503-DB4436</styleUrl> <ExtendedData> <Data name='opis'> <value>Som desc.</value> </Data> <Data name='Informacje:'> <value>Some information </value> </Data> <Data name='Telefon:'> <value>(22) 333 55 55 (22)</value> </Data> <Data name='E-mail'> <value>qwerty@mail.com</value> </Data> <Data name='Strona:'> <value>www.google.com</value> </Data> <Data name='gx_media_links'> <value>some links</value> </Data> </ExtendedData> <Point> <coordinates>22.912227,52.12221,0.0</coordinates> </Point> </Placemark> </Folder> 

The reason for the incorrect filling in the excessively saturated text with the element; , is it possible, based on the current code, to implement the correct conversion? Or what implementation options should be used in this situation.

Update

I will give the full version of the code to clarify the correctness of reading CSV using CSVHelpera (I have a problem with output to XML, only one line is output from the CSV file):

  using (var sr = new StreamReader(Fd2.FileName)) { var reader = new CsvReader(sr); IEnumerable<DataRecord> records = reader.GetRecords<DataRecord>(); foreach (DataRecord record in records) // (int element in fibarray) (var record in DataRecord) { XElement category = new XElement("Folder", new XElement("name", "NASI PARTNERZY HANDLOWI"), new XElement("Placemark", new XElement("name", record.name), new XElement("description", record.opis + "<br><br>Informacje: " + record.information + "<br>Telefon: " + record.telefon + "<br>E-mail: " + record.mail + "<br>Strona: " + record.strona + "<br>" + record.img), new XElement("styleUrl", record.icon), new XElement("ExtendedData", new XElement("Data", new XAttribute("name", "gx_media_links"), new XElement("value", record.gx))), new XElement("Point", new XElement("coordinates", record.cordinates)))); using (var sw2 = new StreamWriter(xmlFile, false, Encoding.UTF8)) sw2.WriteLine(category); } } 
  • Those. Do you see a non-screened delimiter in the text? - Zufir
  • Yes, for example with telephone numbers: (22) 333 55 55; (22) 333 55 77, they are in the same cell, but there is a separator between them; - IgKos
  • Is the "Values ​​that contain reserved characters (double quotes, commas, semicolons, new line) are framed with double quotes ("); if there are quotes in the value, they are represented in the file as two quotes in a row. "? - Zufir
  • one
    @IgKos: Last problem in the StreamWriter constructor: you specified false as the second parameter, i.e., you have forbidden it to append to the old file. Here it is, each time and overwrites the previous line with a new one. - VladD
  • one
    @IgKos: Generally, it is expensive to open / close a file on every line. Do better like this: pastebin.com/Y4798eXp - VladD

2 answers 2

If field values ​​do not begin with ";" - it is possible so:

 let fields = str.Split(new[] { "\";" }, StringSplitOptions.None) .Select(x => x.Trim().Substring(1)) 
  • It works, thanks. - IgKos

Please stop handling the CSV files!

CSV is not as simple as it seems. Of the most frequent problems:

  • the presence of a separator inside the cell values ​​("some; data")
  • the presence of the transfer of lines within the cell values ​​(and transfers of different formats - Windows, Unix, Mac)
  • double quotes inside shielded cell values ​​("some" "data")

Therefore, even if there is a well-formed file, the trivial solution is to split it into lines, and to split each line with string.Split()'ом is not correct.

Use the ready-made library, the authors of which took care of formatting. For example, CsvHelper . As an extreme option (if you are not satisfied with the performance of ready-made libraries or you have some kind of custom CSV), you can write your own parser that will handle the most common problems ( example of a draft parser using a finite state machine ).

  • one
    You are absolutely right, and processing by "hands" is the result of insufficient experience and the need for quick results. In the coming days, get acquainted with the technology. Perhaps, if you, at hand, have good examples, I ask to share. - IgKos
  • @IgKos in the documentation for CsvHelper'u everything is there. You need the CsvParser class and the ReadLine() method. - andreycha
  • Still, I will ask for help with the code, since it was not possible to implement the functionality without special experience and many living examples on the Internet. - IgKos