#c# #xml #csv
#c# #xml #csv
Вопрос:
Я получаю следующее XML-сообщение от банкомата, обрабатывающего депозиты. Теперь он должен быть преобразован в CSV и сохранен. Поскольку это не просто структурированный XML, у меня есть некоторые проблемы с ним. Я не могу отображать данные по отдельности в формате CSV.
<?xml version="1.0" encoding="UTF-8"?>
<RemoteMessage operation="Device OK" DeviceID="SDM100-02378" CustomerCode="12345" Date="2020-09-06" Time="14:30:10" NOP="3013">
<content>
<count machineId="4" den="0.05" curr="CHF" qty="9" type="C" N="0" sType="B"/>
</content>
<devStatus>
<dev name="BDM" machineId="3" mod="SDM 100S" err="KO" devS="2"/>
<dev name="CDM" machineId="4" mod="CDS 508 (BV DE0)" err="OK" clean="0" door="0" devS="1" bag="2" cov="0" blk="00000000" ext="0"/>
</devStatus>
</RemoteMessage>
Вот что я пробовал:
txtXML.Text = File.ReadAllText(comboBoxPath.Text);
var input = txtXML.Text;
// 1) Replace closing and opening tags with commas.
// Include quotes in case any values have commas in them.
var result = Regex.Replace(input, @"(S)</[^>]*>s*<[^>]*>(S)", "$1","$2");
// 2) Put in CSV line breaks and remove xml delimiters, include leading and trailing quotes
result = Regex.Replace(result, @"</[^>]*>s*</RemoteMessage>s*<RemoteMessage>s*<[^>]*>", "rn");
// 3) Remove remaining tags and trim any whitespace
result = Regex.Replace(result, @"s*<.*>s*", "");
// 4) put in header row and first and last quotes
result = DateTime.Now.ToString("yyyy.MM.dd") ", " DateTime.Now.ToString("HH:mm:ss") ", " "d, " "content" result "";
txtCSV.Text = resu<
Я тоже пробовал это:
using (CsvWriter writer = new CsvWriter(@"C:UsersAdminDesktopCSVMessage.csv"))
using (XmlRecordReader reader = new XmlRecordReader(@"C:UsersAdminDesktopXMLMessage.xml", "RemoteMessage/RemoteMessage"))
{
reader.Columns.Add("content", "content");
//reader.Columns.Add("devStatus", "devStatus");
writer.Write("machineId");
//writer.Write("name");
writer.EndRecord();
while (reader.ReadRecord())
{
writer.Write(reader["machineId"]);
//writer.Write(reader["name"]);
writer.EndRecord();
}
reader.Close();
writer.Close();
}
В обоих примерах указаны только заголовки, но нет значений. Кто-нибудь может помочь?
Ответ №1:
Попробуйте выполнить следующее :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication176
{
class Program
{
const string INPUT_FILENAME = @"c:temptest.xml";
const string OUTPUT_FILENAME = @"c:temptest.csv";
static void Main(string[] args)
{
string xml = File.ReadAllText(INPUT_FILENAME);
StringReader sReader = new StringReader(xml);
XmlReader xReader = XmlReader.Create(sReader);
XmlSerializer serializer = new XmlSerializer(typeof(RemoteMessage));
RemoteMessage remoteMessage = (RemoteMessage)serializer.Deserialize(xReader);
string[] headers = new string[] {
"operation",
"DeviceID",
"CustomerCode",
"Date",
"NOP",
"machineId",
"den",
"curr",
"qty",
"type",
"N",
"sType",
"name",
"machineID",
"mod",
"err",
"devS"
};
StreamWriter writer = new StreamWriter(OUTPUT_FILENAME);
writer.WriteLine(string.Join(",", headers));
string remoteMessageStr = string.Join(",",
remoteMessage.operation,
remoteMessage.DeviceID,
remoteMessage.CustomerCode,
remoteMessage.Date.Add(remoteMessage.GetTime()),
remoteMessage.NOP
);
string content = string.Join(",",
remoteMessage.content.First().machineId,
remoteMessage.content.First().den,
remoteMessage.content.First().curr,
remoteMessage.content.First().qty,
remoteMessage.content.First().type,
remoteMessage.content.First().N,
remoteMessage.content.First().sType
);
foreach(Device device in remoteMessage.devices)
{
string deviceStr = string.Join(",",
device.name,
device.machineId,
device.mod,
device.err,
device.devS
);
writer.WriteLine(string.Join(",", remoteMessageStr, content, deviceStr));
}
writer.Flush();
writer.Close();
}
}
public class RemoteMessage
{
[XmlAttribute()]
public string operation { get; set; }
[XmlAttribute()]
public string DeviceID { get; set; }
[XmlAttribute()]
public string CustomerCode { get; set; }
[XmlAttribute()]
public DateTime Date { get; set; }
[XmlAttribute()]
private TimeSpan _time { get; set; }
[XmlAttribute()]
public DateTime Time
{
get { return new DateTime().Add(_time); }
set { _time = value.TimeOfDay; }
}
[XmlAttribute()]
public int NOP { get; set; }
[XmlArray("content")]
[XmlArrayItem("count")]
public List<Content> content { get; set; }
[XmlArray("devStatus")]
[XmlArrayItem("dev")]
public List<Device> devices { get; set; }
public TimeSpan GetTime()
{
return _time;
}
}
public class Content
{
[XmlAttribute()]
public int machineId { get; set; }
[XmlAttribute()]
public decimal den { get; set; }
[XmlAttribute()]
public string curr { get; set; }
[XmlAttribute()]
public int qty { get; set; }
[XmlAttribute()]
public string type { get; set; }
[XmlAttribute()]
public int N { get; set; }
[XmlAttribute()]
public string sType { get; set; }
}
public class Device
{
[XmlAttribute()]
public string name { get; set; }
[XmlAttribute()]
public int machineId { get; set; }
[XmlAttribute()]
public string mod { get; set; }
[XmlAttribute()]
public string err { get; set; }
[XmlAttribute()]
public string devS { get; set; }
}
}
Комментарии:
1. Вау, большое вам спасибо, я интегрировал это в «Приложение формы» и создал три класса. Документ создается, но остается пустым. Затем создается Excel с защитой от записи. Есть идеи?
2. Я протестировал его с помощью консольного приложения, и все работает нормально. Однако при использовании приложения формы созданный документ остается пустым. Сообщения об ошибке нет. Есть идеи?
3. Нет никакой разницы в запуске этого кода в форме или консоли. Поставьте точку останова и убедитесь, что код выполняется. Убедитесь, что вы читаете правильный XML-файл.
4. Я позволяю отображаемому XML-файлу отображаться в текстовом поле, поэтому я могу быть уверен, что он будет прочитан правильно. Пути одинаковы для обоих приложений. Код также абсолютно идентичен. Я не могу объяснить, почему вывод выводится с помощью консоли, а не с помощью формы.
5. Я нашел проблему. Теперь все идет так, как должно. Большое спасибо!!