Анализ данных с различной структурой от XML до List<string>

У меня есть XML-данные, представляющие один клиент, загруженный в веб-браузер, например:

<!--?xml version = "1.0" encoding = "UTF-8" ?-->
<html>
<head></head>
<body>
    <document>
        <Name>Carl</Name>
        <Surname>Smith</Surename>
        <Age>40</Age>
        <Gender>M</Gender>
    </document>
</body>

и полученная веб-страница отображает данные следующим образом:

Карл Смит 40 М

Указанная веб-страница на самом деле отображает лишь простую строку информации и ничего больше.

С этим есть несколько проблем.

  • Существует 10–15 шаблонов структуры данных XML. Например, в одном шаблоне может отсутствовать возраст, другой будет начинаться с фамилии, а третий будет содержать дополнительную информацию. Это означает, что никакой стандартизации не существует.

  • Каждый клиент имеет в зависимости от шаблона от 68 до 278 (ровно) атрибутов/элементов в соответствующем XML. Таким образом, приведенный выше пример на самом деле настолько прост, насколько он позволяет донести суть.

Как разобрать этот XML в List<string>? Я бы хотел, чтобы в этом списке была одна часть информации из XML в качестве одного элемента в этом списке. Если продолжить пример выше, результат будет выглядеть так:

Список[0] = "Карл"

Список[1] = "Смит"

List[2] = "40" (да, четные числа будут преобразованы в строку)

Список[3] = "М"

и так далее..

Полагаю, ответ будет чем-то вроде Как мне извлечь эти XML-элементы в List<string>? но поскольку мои элементы (атрибуты) каждый раз имеют разные названия, я несколько теряюсь.

Я подозреваю, что код выглядит примерно так (взято из другого поста), но я не знаю, что поставить вместо YXYXYXXYX, поскольку элемент/атрибут меняется для каждой строки:

using System;
using System.Linq;
using System.Xml.Linq;

public class Test
{
    static void Main()
    {

     string _url = _UrlMaker.GetUrl(); //method which extracts URL with the XML data
     WebClient client = new WebClient(); 
     var xml = client.DownloadString(_url); //this should load the XML?

        XDocument doc = XDocument.Parse(xml);

        var list = doc.Root.Elements(YXYXYXXYX)
                           .Select(element => element.Value)
                           .ToList();                
    }
}

Может ли кто-нибудь предоставить мне код для этой проблемы?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это может быть возможным решением:

var url = "your URL";
using var httpClient = new HttpClient()
var response = await httpClient.GetAsync(url);
 
response.EnsureSuccessStatusCode();
var htmlContent = await response.Content.ReadAsStringAsync();

var doc = XDocument.Parse(htmlContent);

var list = doc.Root
       .DescendantsAndSelf()
       .Where(e => !e.HasElements && !string.IsNullOrEmpty(e.Value))
       .Select(e => e.Value.ToString())
       .ToList();

феноменально, спасибо! Точно так же, как г-н. В случае с Нанаяккарой, похоже, так и есть. Мне просто нужно устранить следующую ошибку, и я смогу закрыть эту проблему.

Matěj 28.05.2024 14:11

глупый вопрос, но является ли мой документ вообще XML? Мне сказали, что так и должно быть... но поскольку первая строка (теперь отредактированная) кажется незаконной...

Matěj 28.05.2024 14:27

Нет, на самом деле это HTML. Здесь также есть открывающие и закрывающие теги, но, строго говоря, это не XML.

decius 28.05.2024 14:31

Спасибо! Так могу ли я как-то изменить его на XML или мне следует выбрать другой метод анализа?

Matěj 28.05.2024 14:33

Я снова отредактировал свой ответ. Это должно работать и с этим HTML (если у вас есть все закрывающие теги).

decius 28.05.2024 14:34

спасибо, проблема в том, что мой вывод HTML (формально считавшийся XML) меняется, поэтому я не могу просто поместить его в строку, как в вашем ответе. Есть ли способ скачать html-код?

Matěj 28.05.2024 14:43

Я снова изменил свое сообщение. Это должно работать с любым URL-адресом (когда HTML действителен, не имеет комментариев и т. д.).

decius 28.05.2024 14:54

Давайте продолжим обсуждение в чате.

Matěj 28.05.2024 15:14

спасибо, а можно ли это сделать синхронно?

Matěj 28.05.2024 15:42

Хм... вам следует делать это асинхронно. Это возможно, но не рекомендуется.

decius 28.05.2024 16:53

Мне удалось решить это следующим образом: я загрузил HTML в строку, превратил его в список, удалил первые две строки и снова превратил их в строку, а затем правильно проанализировал его в соответствии с вашими предыдущими инструкциями, не используя асинхронный путь. Большое вам спасибо за ваше время!

Matěj 29.05.2024 10:38
Ответ принят как подходящий

Вы можете получить все значения в список с помощью:

List<string> values = doc.Descendants("document")
                                 .Elements()
                                 .Select(element => element.Value)
                                 .ToList();

Для получения дополнительной информации обратитесь к приведенному ниже коду:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        string xmlData = @"<html>
<head></head>
<body>
    <document>
        <Name>Carl</Name>
        <Surname>Smith</Surname>
        <Age>40</Age>
        <Gender>M</Gender>
    </document>
</body>
</html>";

        
        XDocument doc = XDocument.Parse(xmlData); // load the string as XDocument

        
        List<string> values = doc.Descendants("document")
                                 .Elements()
                                 .Select(element => element.Value)
                                 .ToList(); // get values to a string list

        
        values.ForEach(Console.WriteLine); // Print each value
    }
}

См. прикрепленный файл .netFiddle здесь

Привет! Спасибо, при вызове моего метода я получил эту ошибку: System.Xml.XmlException: «Неожиданное объявление XML. Объявление XML должно быть первым узлом в документе, и перед ним не допускается появление пробелов. Линия 2, позиция 3.' Есть идеи?

Matěj 28.05.2024 13:52

теперь я понимаю, почему первая строка синтаксического анализа XML выглядит так: '<!--?xml version = "1.0"coding = "UTF-8" ?-->', но она должна начинаться с '<? xml'. Возможно, я здесь о многом спрашиваю, но есть ли простой способ изменить это в моем собственном коде?

Matěj 28.05.2024 13:58

Другие вопросы по теме