Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Есть ли какое-то общепринятое правило чтения таких XML? / 16 сообщений из 16, страница 1 из 1
09.10.2019, 01:09
    #39873685
хорошо я согласен
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
В которых заголовки отдельно, затем строки отдельно, поля в них расположены в том же порядке, что и в заголовке.
пример:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
<Head xmlns="http://www.mirpirojok.ru/universal"
						xsi:type="HeadType">
	<ColumnDescription Name="Фамилия"
			Type="Строка"/>
	<ColumnDescription Name="Имя"
			Type="Строка"/>
	<ColumnDescription Name="Отчество"
			Type="Строка"/>
	<ColumnDescription Name="РодительКод1С"
			Type="Строка"/>
	<ColumnDescription Name="Наименование"
			Type="Строка"/>
	<ColumnDescription Name="ПолнНаименование"
			Type="Строка"/>
	<ColumnDescription Name="ДатаНач"
			Type="Дата"/>
	<ColumnDescription Name="ДатаКон"
			Type="Дата"/>
	<ColumnDescription Name="НомерП"
			Type="Null"/>
	<ColumnDescription Name="Город"
			Type="Строка"/>
	<ColumnDescription Name="Страна"
			Type="Строка"/>
</Head>
<Body xmlns="http://www.mirpirojok.ru/universal"
		xsi:type="BodyType">
	<Row>
		<Column Value="Иванов"/>
		<Column Value="Иван"/>
		<Column Value="Ваныч"/>
		<Column Value="4523453456"/>
		<Column Value="DDDDFFFF"/>
		<Column Value="BBBB"/>
		<Column Value="2019-01-01T00:00:00"/>
		<Column Value="0001-01-01T00:00:00"/>
		<Column Value="69"/>
		<Column Value="Берлин"/>
		<Column Value="Россия"/>
	</Row>
	<Row>
		<Column Value="Петров"/>
		<Column Value="Пётр"/>
		<Column Value="Петрыч"/>
		<Column Value="4523453456"/>
		<Column Value="DDDDFFFF"/>
		<Column Value="BBBB"/>
		<Column Value="2019-01-01T00:00:00"/>
		<Column Value="0001-01-01T00:00:00"/>
		<Column Value="70"/>
		<Column Value="Берлин"/>
		<Column Value="Россия"/>
	</Row>


Я бы с удовольствием читал эту xml с помощью встроенных средств, только не всегда понятно, что за поле я читаю. Приходится всякими внутренними циклами и массивами исхищряться. Но такой код другим людям боюсь показывать)
Как это делается правильно?
...
Рейтинг: 0 / 0
09.10.2019, 03:57
    #39873702
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
хорошо я согласен,

ну как.. удобно наверное читать в DataTable. сначала считываете колонки, затем данные, записывая значения в строку по порядку. если данных много, то читать методом sax.
...
Рейтинг: 0 / 0
09.10.2019, 08:03
    #39873718
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
хорошо я согласенКак это делается правильно?
Зависит от того, что вы подразумеваете под "правильно", что нужно в итоге, и от объема данных. Если последний позволяет выполнить разбор DOM, то можно причесать исходный XML к удобоваримому виду с помощью XSLT. Например, если есть уверенность, что все имена колонок могум быть именами атрибутов, то я бы сделал так:
Исходный XML:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Head xmlns="http://www.mirpirojok.ru/universal" xsi:type="HeadType">
    <ColumnDescription Name="Фамилия" Type="Строка" />
    <ColumnDescription Name="Имя" Type="Строка" />
    <ColumnDescription Name="Отчество" Type="Строка" />
    <ColumnDescription Name="РодительКод1С" Type="Строка" />
    <ColumnDescription Name="Наименование" Type="Строка" />
    <ColumnDescription Name="ПолнНаименование" Type="Строка" />
    <ColumnDescription Name="ДатаНач" Type="Дата" />
    <ColumnDescription Name="ДатаКон" Type="Дата" />
    <ColumnDescription Name="НомерП" Type="Null" />
    <ColumnDescription Name="Город" Type="Строка" />
    <ColumnDescription Name="Страна" Type="Строка" />
  </Head>
  <Body xmlns="http://www.mirpirojok.ru/universal" xsi:type="BodyType">
    <Row>
      <Column Value="Иванов" />
      <Column Value="Иван" />
      <Column Value="Ваныч" />
      <Column Value="4523453456" />
      <Column Value="DDDDFFFF" />
      <Column Value="BBBB" />
      <Column Value="2019-01-01T00:00:00" />
      <Column Value="0001-01-01T00:00:00" />
      <Column Value="69" />
      <Column Value="Берлин" />
      <Column Value="Россия" />
    </Row>
    <Row>
      <Column Value="Петров" />
      <Column Value="Пётр" />
      <Column Value="Петрыч" />
      <Column Value="4523453456" />
      <Column Value="DDDDFFFF" />
      <Column Value="BBBB" />
      <Column Value="2019-01-01T00:00:00" />
      <Column Value="0001-01-01T00:00:00" />
      <Column Value="70" />
      <Column Value="Берлин" />
      <Column Value="Россия" />
    </Row>
  </Body>
</root>


XSLT:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:pirojok="http://www.mirpirojok.ru/universal">

  <xsl:output method="xml" />

  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>
  
  <xsl:template match="root">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="pirojok:Body">
    <root>
      <xsl:apply-templates />
    </root>
  </xsl:template>

  <xsl:template match="pirojok:Row">
    <row>
      <xsl:for-each select="pirojok:Column">
        <xsl:call-template name="ColumnName">
          <xsl:with-param name="ord" select="position()" />
        </xsl:call-template>
      </xsl:for-each>
    </row>
  <xsl:apply-templates />
  </xsl:template>

  <xsl:template name="ColumnName">
    <xsl:param name="ord" />
    <xsl:call-template name="ColumnNameAttribute">
      <xsl:with-param name="attrname" select="ancestor::root/pirojok:Head/pirojok:ColumnDescription[$ord]/@Name" />
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="ColumnNameAttribute">
    <xsl:param name="attrname" />
    <xsl:attribute name="{$attrname}">
      <xsl:value-of select="@Value" />
    </xsl:attribute>
  </xsl:template>
  <xsl:template match="text()" />
</xsl:stylesheet>


Результат:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
<root xmlns:pirojok="http://www.mirpirojok.ru/universal">
  <row
    Фамилия="Иванов"
    Имя="Иван"
    Отчество="Ваныч"
    РодительКод1С="4523453456"
    Наименование="DDDDFFFF"
    ПолнНаименование="BBBB"
    ДатаНач="2019-01-01T00:00:00"
    ДатаКон="0001-01-01T00:00:00"
    НомерП="69"
    Город="Берлин"
    Страна="Россия" />
  <row
    Фамилия="Петров"
    Имя="Пётр"
    Отчество="Петрыч"
    РодительКод1С="4523453456"
    Наименование="DDDDFFFF"
    ПолнНаименование="BBBB"
    ДатаНач="2019-01-01T00:00:00"
    ДатаКон="0001-01-01T00:00:00"
    НомерП="70"
    Город="Берлин"
    Страна="Россия" />
</root>


Дальше можно просто создать класс, промапить его атрибутами, и получить список экземпляров с помощью XmlSerializer - как-то так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
class Program
{
  public static void Main(string[] args)
  {
    var xd = new XmlDocument();
    var xslt = new XslCompiledTransform();
    using(var fs = new FileStream(@"D:\Trash\1.xsl", FileMode.Open))
    using(var xr = XmlReader.Create(fs))
      xslt.Load(xr);
    using(var fs = new FileStream(@"D:\Trash\src.xml", FileMode.Open))
    using(var xr = XmlReader.Create(fs))
    using (var xw = xd.CreateNavigator().AppendChild())
      xslt.Transform(xr, null, xw);
    using(var xr = xd.CreateNavigator().ReadSubtree())
    {
      var items = ((Root) new XmlSerializer(typeof(Root)).Deserialize(xr)).Items;
      Console.WriteLine(items);
    }
    Console.WriteLine("done");
    Console.ReadKey(true);
  }
}

[XmlRoot(ElementName = "root", Namespace = "")]
public class Root
{
  [XmlElement("row")]
  public List<XmlItem> Items { get; set; }
}

public class XmlItem
{
  [XmlAttribute("Фамилия")]
  public string Surname { get; set; }
  [XmlAttribute("Имя")]
  public string Name { get; set; }
  [XmlAttribute("Отчество")]
  public string MiddleName { get; set; }
  [XmlAttribute("РодительКод1С")]
  public string Parent1SCode { get; set; }
  [XmlAttribute("Наименование")]
  public string Name2 { get; set; }
  [XmlAttribute("ПолнНаименование")]
  public string FullName2 { get; set; }
  [XmlAttribute("ДатаНач")]
  public DateTime BeginDate { get; set; }
  [XmlAttribute("ДатаКон")]
  public DateTime EndDate { get; set; }
  [XmlAttribute("НомерП")]
  public int NP { get; set; }
  [XmlAttribute("Город")]
  public string City { get; set; }
  [XmlAttribute("Страна")]
  public string State { get; set; }
}
...
Рейтинг: 0 / 0
09.10.2019, 08:25
    #39873723
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
...
Рейтинг: 0 / 0
09.10.2019, 10:06
    #39873787
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
Сон Веры Павловны,

чёт мне кажется, это лишнее. можно сразу читать xml со структурой его данных. явно она динамическая, исходя из наличия секции Header.
...
Рейтинг: 0 / 0
09.10.2019, 22:06
    #39874324
хорошо я согласен
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
вообще, мне изначально это для SSIS нужно было.
Очень крутое решение! спасибо. Буду подробнее смотреть xslt
...
Рейтинг: 0 / 0
10.10.2019, 06:51
    #39874378
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
хорошо я согласенвообще, мне изначально это для SSIS нужно было.
О. Так может, действительно все эти XSLT и XmlSerializer лишние. Насколько я понимаю, конечная задача - разобрать этот XML, и залить куда-то в базу? Может, проще было бы передать его как есть на сервер (в табличную функцию, ХП, или скрипт), и там разобрать с помощью XQuery?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
declare
  @xdata xml=N'<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">.....</root>';
;with xmlnamespaces('http://www.mirpirojok.ru/universal' as p)
select
  t.n.value('p:Column[1]/@Value', 'nvarchar(255)') Surname,       -- Фамилия
  t.n.value('p:Column[2]/@Value', 'nvarchar(255)') Name,          -- Имя
  t.n.value('p:Column[3]/@Value', 'nvarchar(255)') MiddleName,    -- Отчество
  t.n.value('p:Column[4]/@Value', 'nvarchar(255)') Parent1SCode,  -- РодительКод1С
  t.n.value('p:Column[5]/@Value', 'nvarchar(255)') Name2,         -- Наименование
  t.n.value('p:Column[6]/@Value', 'nvarchar(255)') FullName2,     -- ПолнНаименование
  t.n.value('p:Column[7]/@Value', 'date') BeginDate,              -- ДатаНач
  t.n.value('p:Column[8]/@Value', 'date') EndDate,                -- ДатаКон
  t.n.value('p:Column[9]/@Value', 'int') NP,                      -- НомерП
  t.n.value('p:Column[10]/@Value', 'nvarchar(255)') City,         -- Город
  t.n.value('p:Column[11]/@Value', 'nvarchar(255)') State         -- Страна
from @xdata.nodes('/root/p:Body/p:Row') t(n)
...
Рейтинг: 0 / 0
10.10.2019, 08:56
    #39874401
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
В качестве утренней разминки :)
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
var xElement = XElement.Load("BadAndUgly.xml");

var columns = xElement.Descendants("ColumnDescription")
	.Select(cd => new {
		Name = cd.Attribute("Name").Value,
		Type = cd.Attribute("Type").Value
	})
	.ToArray();

var result = xElement.Descendants("Row")
	.Select(row =>
		row.Descendants("Column")
		   .Select((col, ord) => new {
			   columns[ord].Name,
			   columns[ord].Type,
			   col.Attribute("Value").Value
		   })
		   .ToDictionary(col => col.Name, col => new {
			   col.Type,
			   col.Value
		   })
	)
	.ToArray();
...
Рейтинг: 0 / 0
10.10.2019, 09:15
    #39874406
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
Сон Веры Павловны,

решение конечно рабочее, но не айс.

там заголовок есть, надо от него читать данные, чтобы потом сюрпризов не было, сталкивался не раз, когда разработчик МОГ работать с моделью, ну хотя бы валидировать, но нет.. зачем? решим в лоб :)
...
Рейтинг: 0 / 0
10.10.2019, 09:18
    #39874408
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
нужно данные считывать именно так:

row["Фамилия"]
row["Отчество"]

...

вот как это приходит в схеме.
там же не для красоты секция <Head>.
и не для того, чтобы глядя на него захардкодили решение.
если конечно это не разовая операция.

это раз.

два. при работе с XML, содержащие табличные данные, всегда нужно использовать SAX. всегда.
какой ещё XElement.Load?
...
Рейтинг: 0 / 0
10.10.2019, 09:32
    #39874414
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
hVosttпри работе с XML, содержащие табличные данные, всегда нужно использовать SAX. всегда.
Ну, я бы не был так категоричен. Это то же, что и DataSet vs DataReader - инога более подходит одно, иногда другое, it depends.

hVosttкакой ещё XElement.Load?
LINQ to XML , вестимо
...
Рейтинг: 0 / 0
10.10.2019, 10:08
    #39874439
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
hVosttСон Веры Павловны,

решение конечно рабочее, но не айс.

там заголовок есть, надо от него читать данные, чтобы потом сюрпризов не было, сталкивался не раз, когда разработчик МОГ работать с моделью, ну хотя бы валидировать, но нет.. зачем? решим в лоб :)
Какая при такой структуре валидация? Тут даже XSD никакой не напишешь. Остается только программная валидация при загрузке значений, и на заголовок тут уже можно положить. Ну, собственно, в последнем примере валидация вполне есть - по типам данных. По позициям она не нужна, поскольку ТС писал, что строки идут в той же последовательности, что и заголовки.
...
Рейтинг: 0 / 0
10.10.2019, 15:12
    #39874659
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
Сон Веры ПавловныКакая при такой структуре валидация? Тут даже XSD никакой не напишешь. Остается только программная валидация при загрузке значений, и на заголовок тут уже можно положить. Ну, собственно, в последнем примере валидация вполне есть - по типам данных. По позициям она не нужна, поскольку ТС писал, что строки идут в той же последовательности, что и заголовки.

Ну в смысле, какая?

Если ты получаешь данные запроса, у тебя названия колонок есть. Ты же не обращаешься к значениям по индексу? :) Я понимаю, в каком-нибудь ORM такое может использоваться, но не в человеческих исходниках.


fkthatНу, я бы не был так категоричен. Это то же, что и DataSet vs DataReader - инога более подходит одно, иногда другое, it depends.

Никаким It depends-ом тут не пахнет. Табличные данные надо грузить SAX-ом. Или считаете, это пипец как сложно? Код привести? :) Он не сложнее LINQ to XML. Если не знаем, то так лучше и сказать.
...
Рейтинг: 0 / 0
10.10.2019, 15:16
    #39874665
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
Сон Веры ПавловныПо позициям она не нужна, поскольку ТС писал, что строки идут в той же последовательности, что и заголовки.

Я про заголовок. Заголовок описывает структуру данных. Мы берём данные из набора согласно указанной в заголовке структуры. Обращаемся по именам колонок, а не по индексу. Дополнительно, конечно ещё и типы нужно проверить, но это уже вышка какая-то :)
...
Рейтинг: 0 / 0
10.10.2019, 16:03
    #39874707
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
hVosttНикаким It depends-ом тут не пахнет. Табличные данные надо грузить SAX-ом.
Да. Тут, похоже, все уже знают, что делать всегда надо только так, как герр hVost считает. Ну, надо, значит надо, бог с тобой.
...
Рейтинг: 0 / 0
10.10.2019, 16:32
    #39874735
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Есть ли какое-то общепринятое правило чтения таких XML?
fkthathVosttНикаким It depends-ом тут не пахнет. Табличные данные надо грузить SAX-ом.
Да. Тут, похоже, все уже знают, что делать всегда надо только так, как герр hVost считает. Ну, надо, значит надо, бог с тобой.


Вовсе не обязательно включать вот этот унылый детский сад.

Если с чем не согласны, пишите. Я же могу пояснить свои слова, если для вас это совсем не очевидно.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Есть ли какое-то общепринятое правило чтения таких XML? / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]