c # - получить дерево данных из файла XML - PullRequest
0 голосов
/ 28 октября 2019

У меня есть XML-файл, который имеет много дочерних элементов:

<Docs>
    <Doc>
        <DocType>x</DocType>
        <DocNumber>xxx</DocNumber>
        <DocNumberSeries>xx</DocNumberSeries>
        <DocDate>xxxx-xx-xx</DocDate>
        <DocCause>
            <Id>xx</Id>
            <Code/>
            <Name>xx</Name>
        </DocCause>
        <Anag>
            <Name>NameCompany</Name>
            <Address>xx</Address>
            <ZipCode>xx</ZipCode>
            <City>xx</City>
            <Province>xx</Province>
            <CountryCode>xx</CountryCode>
            <PhoneNumber>xx</PhoneNumber>
            <CellularNumber/>
            <FaxNumber>xx</FaxNumber>
            <EmailAddress>xx</EmailAddress>
            <VatNumber>xx</VatNumber>
            <PersonalID>xx</PersonalID>
        </Anag>
        <DestinationAddress>
            <Name>xxL</Name>
            <Address>xx</Address>
            <ZipCode>xx</ZipCode>
            <City>xx</City>
            <Province>xx</Province>
            <CountryCode>xx</CountryCode>
            <PhoneNumber>xx</PhoneNumber>
            <FaxNumber>xx</FaxNumber>
        </DestinationAddress>
        <Payment>
            <Code/>
            <Name>xx</Name>
        </Payment>
        <DocRows>
            <DocRow>
                <RowType>1</RowType>
                <Product>
                    <Code>LSML1710</Code>
                </Product>
                <Description></Description>
                <Quantity></Quantity>
                <Price></Price>
                <Tax>
                    <Tax>
                        <Id>xx</Id>
                        <Code/>
                        <Name>xx</Name>
                        <PercentAmount>xx</PercentAmount>
                        <IndPercentAmount>x</IndPercentAmount>
                        <FixedAmount>x</FixedAmount>
                    </Tax>
                </Tax>
            </DocRow>
        </DocRows>
    ...
    </Doc>

Например, одна из вещей, которые я хочу сделать, - это получить данные внутри тега Doc, а затем Anag.

На данный момент у меня есть следующие классы:

public class Anag
{
    public string RagioneSociale { get; set; }
    public string Indirizzo { get; set; }
    public string CAP { get; set; }
    public string Citta { get; set; }
    public string Provincia { get; set; }
    public string CodiceNazione { get; set; }
    public string Telefono { get; set; }
    public string Cellulare { get; set; }
    public string Email { get; set; }
}

public class Doc
{
    public string DocNumber { get; set; }
    public Anag Anags { get; set; }
}
List<Doc> results = contentFile.Descendants("Doc").Select(doc => new Doc // var results = contentFile.Descendants("Doc").SelectMany(doc => doc.Descendants(doc.Name.Namespace + "Anag").Select(anag => new
{
    DocNumber = (string)doc.Element(doc.Name.Namespace + "DocNumber"),
    Anags = doc.Descendants(doc.Name.Namespace + "Anag").Select(anag => new Anag
    {
        RagioneSociale = (string)anag.Element(anag.Name.Namespace + "Name"),
        Indirizzo = (string)anag.Element(anag.Name.Namespace + "Address"),
        CAP = (string)anag.Element(anag.Name.Namespace + "ZipCode"),
        Provincia = (string)anag.Element(anag.Name.Namespace + "Province"),
        Telefono = (string)anag.Element(anag.Name.Namespace + "PhoneNumber"),
        Cellulare = (string)anag.Element(anag.Name.Namespace + "CellularNumber"),
        Email = (string)anag.Element(anag.Name.Namespace + "EmailAddress"),
        Citta = (string)anag.Element(anag.Name.Namespace + "City")
    }),
}).ToList();

Этот последний код выдает ошибку:

Невозможно неявно преобразовать тип system.collections.generic.IEnumerable<nameProject.Classes.Anag> в <NameProject.Classes.Anag>.

Конечный результат, который мне нужен, это список с данными и потомками этого XML:

Список:

+ Doc=> 
 {DocNumber}
+ Anag => { Address .. , Name.. .. )   (not a list ! )
+ DestinationAddress => { Address.... Name..)

, чтобы я могпреобразовать только в файл .csv.

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Поскольку вы уже столкнулись с проблемой создания классов, почему бы не позволить десериализатору выполнить эту работу за вас?

Вот как:

XmlSerializer serializer = new XmlSerializer(typeof(Root));
using (var reader = new StreamReader(xmlFilePath))
{
    List<Doc> docs = ((Root)serializer.Deserialize(reader)).Docs;
}

Теперь вам просто нужно добавить несколько тегов в свойства вашего класса, чтобы они соответствовали именам xml.

[Serializable, XmlRoot("Docs")]
public class Root
{
    [XmlElement("Doc")]
    public List<Doc> Docs { get; set; }
}

public class Doc
{
    public string DocNumber { get; set; }

    [XmlElement("Anag")]
    public Anag Anags { get; set; }
}

public class Anag
{
    [XmlElement("Name")]
    public string RagioneSociale { get; set; }

    [XmlElement("Address")]
    public string Indirizzo { get; set; }

    [XmlElement("ZipCode")]
    public string CAP { get; set; }

    [XmlElement("City")]
    public string Citta { get; set; }

    [XmlElement("Province")]
    public string Provincia { get; set; }

    [XmlElement("CountryCode")]
    public string CodiceNazione { get; set; }

    [XmlElement("PhoneNumber")]
    public string Telefono { get; set; }

    [XmlElement("CellularNumber")]
    public string Cellulare { get; set; }

    [XmlElement("EmailAddress")]
    public string Email { get; set; }
}
0 голосов
/ 28 октября 2019

Просто попробуйте использовать функцию «Специальная вставка» для генерации классов для разбора. Вы 100% не получите исключение.

  1. Crtl + A на весь xml, скопировать в буфер обмена
  2. Затем создать новый класс в вашем проекте. Нажмите «Редактировать» -> «Специальная вставка» -> «Вставить XML какклассы "
  3. Измените синтаксический анализ на использование типа" RootNode "в вставленном классе
  4. Постройте и попробуйте.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...