Здравствуйте. У меня в проекте ASP.NET создаётся xml файл. Потом он пишется в таблицу базы данных Oracle. Потом отдельным консольным приложением я его оттуда читаю и должен разбить назад на данные по полям. И записать эти поля уже в итоговую таблицу где они должны храниться. Вот как выглядит мой xml-ка.
<?xml version="1.0" encoding="utf-8"?>
<SteelSheet>
<Fuse>1500</Fuse>
<SteelGrades>Криогенная</SteelGrades>
<Storage>США</Storage>
<Length>200</Length>
<Width>100</Width>
<Thickness>50</Thickness>
<ShippingDate>25.03.2015</ShippingDate>
<Acomment>Комментарий</Acomment>
<DateManufacture>13.01.2015</DateManufacture>
</SteelSheet>
А вот как я её читаю:
class Program
{
static void Main(string[] args)
{
String str = "select T.xmldoc.getClobVal() as name from Transfer_table T";
using (OracleConnection con = new OracleConnection("Data Source=XE;User ID=Mydb;Password=111292;Unicode=True"))
{
con.Open();
using (OracleCommand com = new OracleCommand(str, con))
{
using (OracleDataReader reader = com.ExecuteReader())
{
while (reader.Read())
{
String xml = reader.GetString(0);
Console.WriteLine(xml);
}
}
}
}
Console.ReadKey();
}
}
И мне нужно вытащить чисто значения которые между тегов. 1500 отсюда нужно вытащить только 1500 в соответствующую переменную fuse. И так далее всю xml-ку. Можете подсказать как это не сложно и не затратно сделать? Может у кого то есть наброски кода. Как это можно сделать. Спасибо заранее.
В вашем конкретном случае есть несколько подходов.
Я постараюсь описать их максимально доступно.
XmlSerializer
Копируете текст этой XML в буфер обмена.
Открываете Visual Studio
, меню Edit
- Paste Special
- Paste XML As Classes
.
Студия распарсит вашу XML-ку и создаст её объектную модель, в данном случае это будет всего один класс, так как XML имеет довольно простую структуру.
У меня появился такой код:
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class SteelSheet
{
private ushort fuseField;
private string steelGradesField;
private string storageField;
private byte lengthField;
private byte widthField;
private byte thicknessField;
private string shippingDateField;
private string acommentField;
private string dateManufactureField;
/// <remarks/>
public ushort Fuse
{
get
{
return this.fuseField;
}
set
{
this.fuseField = value;
}
}
/// <remarks/>
public string SteelGrades
{
get
{
return this.steelGradesField;
}
set
{
this.steelGradesField = value;
}
}
/// <remarks/>
public string Storage
{
get
{
return this.storageField;
}
set
{
this.storageField = value;
}
}
/// <remarks/>
public byte Length
{
get
{
return this.lengthField;
}
set
{
this.lengthField = value;
}
}
/// <remarks/>
public byte Width
{
get
{
return this.widthField;
}
set
{
this.widthField = value;
}
}
/// <remarks/>
public byte Thickness
{
get
{
return this.thicknessField;
}
set
{
this.thicknessField = value;
}
}
/// <remarks/>
public string ShippingDate
{
get
{
return this.shippingDateField;
}
set
{
this.shippingDateField = value;
}
}
/// <remarks/>
public string Acomment
{
get
{
return this.acommentField;
}
set
{
this.acommentField = value;
}
}
/// <remarks/>
public string DateManufacture
{
get
{
return this.dateManufactureField;
}
set
{
this.dateManufactureField = value;
}
}
}
В принципе с этим можно уже работать, но я рекомендую внимательно изучить этот класс и отрефакторить его:
Во-первых, используя "плюшки" современных версий C#
можно избавиться от лишних полей, заменив их автосвойствами, например следующий код:
private ushort fuseField;
public ushort Fuse
{
get
{
return this.fuseField;
}
set
{
this.fuseField = value;
}
}
Можно заменить на одно автосвойство:
public ushort Fuse { get; set; }
Внимание, это делать нужно только если на ваши свойства не будет наложена никакая "бизнес-логика".
Во-вторых, проверьте правильно ли студия вывела типы для ваших свойств, например, если Fuse
может быть также отрицательным числом, имеет смысл изменить тип свойства на short/int/long
вместо беззнакового ushort
.
И т. д.
Теперь мы можем воспользоваться этой моделью и десериализовать ее:
XmlSerializer serializer = new XmlSerializer(typeof(SteelSheet));
SteelSheet steelSheet;
using (var sr = new StringReader(xml))
steelSheet = (SteelSheet)serializer.Deserialize(sr);
Теперь у нас в steelSheet
готовый объект, представляющий нашу XML и им можно пользоваться:
Console.WriteLine(steelSheet.Fuse);
2. Использование технологии LinqToXml
В этом подходе вам не понадобится создавать объектную модель вашей XML, что уменьшит код, но с другой стороны усложнит немного логику и не даст удобства использования полноценного объекта (типизация, подсказки IntelliSense).
Давайте просто загрузим нашу XML в объект типа XDocument
:
XDocument doc;
using (var sr = new StringReader(xml))
doc = XDocument.Load(sr);
Всё! Теперь можно извлечь любой элемент/атрибут просто пройдя по дереву XML (главное не ошибиться с именами):
Console.WriteLine((int)doc.Element("SteelSheet").Element("Fuse"));
или:
Console.WriteLine((int)doc.Root.Element("Fuse"));
3. Использование средств, предоставляемых драйвером ODP.NET
по извлечению полей типа XmlType
Если вы используете новый Official Oracle ODP.NET, Managed Driver
, а я вам рекомендую использовать именно его, вы можете воспользоваться методом GetOracleXmlType
класса OracleDataReader
.
В этом случае вам не нужно кастовать XmlType
в строку на стороне сервера:
select T.xmldoc from Transfer_table T
тогда код чтения перепишите так:
XmlDocument doc = reader.GetOracleXmlType(0).GetXmlDocument();
т.е. на выходе получите уже готовый экземпляр XmlDocument
, хотя он немного устарел и немного более тяжеловеснее чем XDocument
, но, с другой стороны, работать с ним на стороне клиента может быть выгоднее чем кастовать XmlType
в строку на стороне сервера (а может и нет - надо проверять):
int fuse = int.Parse(doc["SteelSheet"]["Fuse"].InnerText);
Console.WriteLine(fuse);
Считаю что стоит предупредить автора вопроса, что возможно выбран не совсем правильный подход к хранению информации. Т.к. у вас используется БД, возможно стоит создать отдельную таблицу со всеми этими полями (что у вас в xml), и уже выгружать данные запросами к БД, например используя entity framework. Это будет более правильно.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
при сравнении данным методом "а" строковой и "В", будет ли метод использовать код символов в юникод? У а – 97, у В – 66Значит если сравнить их без...
Добрый вечер, друзьяЗадаю данный вопрос не для поднятия холиваров, хочу выяснить для себя с чего начать
Нужно реализовать выбор через ComboBox нужной строки и сделать так чтобы он выводился в ReadOnly TextBox