Как получить доступ к различным элементам XML? - PullRequest
0 голосов
/ 25 июня 2018

У меня есть XML, который содержит различную информацию о flightPlan. Мне нужно взять данные этого плана полета, используя метку «RoutePoints». Пример ниже представляет собой псевдокод для представления структуры. Символ «+» обозначает, что раздел может расширяться.

    <RoutePoints>
      +<a:anyType z:Id="411" i:type="RoutePointTakeOff">
      +<a:anyType z:Id="472" i:type="RoutePoint">
      +<a:anyType z:Id="518" i:type="RoutePoint">
      <a:anyType z:Ref="349" i:nil="true"/>
      <a:anyType z:Ref="272" i:nil="true"/>
      +<a:anyType z:Id="576" i:type="RoutePoint">
      +<a:anyType z:Id="638" i:type="RoutePointLanding">
    </RoutePoints>

Из-за разного типа элементов, которые нужно обрабатывать по-разному. Я пытался использовать инструмент foreach для доступа к этим элементам, пример ниже:

foreach ( var routes in document.Descendants("RoutePoints") ){
    foreach ( var points in routes.Elements() ) {
        if ( points.Attributes(i+"type").First().Value == "RoutePoint") {
            //Processing..
        }
        if ( points.Attributes(i+"type").First().Value == "RoutePointTakeOff") {
            //Processing..
        }
        if ( points.Attributes(i+"nil").First().Value == "true") {
            //Processing..
        }
        if ( points.Attributes(i+"type").First().Value == "RoutePointLanding") {
            //Processing..
        }
    }
}

Когда условие if проверяет атрибуты для сравнения значения, и оно не существует, например, проверяется значение RoutePointTakeOff, и оно не существует, поскольку это значение находится в первой строке, а теперь проверяется во второй строке.

Мне нужно взять элемент, информация, которую мне нужно обработать, находится внутри элементов. Например, внутри RoutePoint мне нужно инициализировать некоторые атрибуты со значениями, которые содержат. Внутри RoutePointTakeOff мне нужно выполнить несколько алгоритмов. Проблема в том, что мне нужно выполнить разные функции в зависимости от секции, где указатель находится

Я - новое программирование на C #, и я уверен, что существуют другие лучшие формы для доступа к данным этого типа.

Не могли бы вы помочь мне получить доступ к этим данным по типу?

Ответы [ 4 ]

0 голосов
/ 25 июня 2018

Я отлаживал и наконец нашел ошибку ...

Я оценивал атрибут "тип", которого нет в строках 4-5. Это привело к ошибке. Более конкретно:

Исключение NullReferenceException было обработано

В конце концов я использую нулевой элемент управления, и теперь он работает.

foreach ( var routes in document.Descendants("RoutePoints") ){
    foreach ( var points in routes.Elements() ) {
        if ( points.Attributes( i + "type").FirstOrDefault != null ){
             if ( points.Attributes(i+"type").First().Value == "RoutePoint") {
                //Processing..
             }
             if ( points.Attributes(i+"type").First().Value == "RoutePointTakeOff") {
                //Processing..
             }
             if ( points.Attributes(i+"type").First().Value == "RoutePointLanding") {
                //Processing..
             }
        } else {
             // Will execute this in rows 4-5    
        }
    }
}
0 голосов
/ 25 июня 2018

Попробуйте следующее:

           XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants().Where(x => x.Name.LocalName == "anyType")
                .Select(x => new {
                    id = x.Attributes().Where(z => z.Name.LocalName == "Id").Select(z => (int)z).FirstOrDefault(),
                    _ref = x.Attributes().Where(z => z.Name.LocalName == "Ref").Select(z => (int)z).FirstOrDefault(),
                    type = x.Attributes().Where(z => z.Name.LocalName == "type").Select(z => (string)z).FirstOrDefault()
                }).ToList();
0 голосов
/ 25 июня 2018

Попробуйте это

public List<DataAttr> GetDataAttribute(XDocument xDocument)
    {
        var dataAttr = new List<DataAttr>();
        foreach (var route in xDocument.Descendants("RoutePoints"))
        {
            foreach (var point in route.Elements())
            {
                if (point.HasElements)
                {
                    dataAttr.AddRange(_getAttributeValues(point.Attributes()));
                }
            }
        }
        return dataAttr;
    }

    private static IEnumerable<DataAttr> _getAttributeValues(IEnumerable<XAttribute> attributes)
    {
        return attributes.Select(x => new DataAttr()
        {
            Name = x.Name.LocalName,
            Value = x.Value
        });
    }
public class DataAttr
{
    public string Name { get; set; }
    public string Value { get; set; }
}

после этой вы можете отсортировать вашу группу данных по имени.

если вы используете этот код, вы не ограничены в имени атрибута. Гудлак.

0 голосов
/ 25 июня 2018

Если вы используете FirstOrDefault вместо First, код работает должным образом, каждый элемент может быть обработан:

foreach (var routes in document.Descendants("RoutePoints"))
{
    foreach (var points in routes.Elements())
    {
        if (points.Attributes(i + "type").FirstOrDefault()?.Value == "RoutePoint")
        {
        }
        if (points.Attributes(i + "type").FirstOrDefault()?.Value == "RoutePointTakeOff")
        {
        }
        if (points.Attributes(i + "nil").FirstOrDefault()?.Value == "true")
        {
        }
        if (points.Attributes(i + "type").FirstOrDefault()?.Value == "RoutePointLanding")
        {
        }
    }
}

Обратите внимание на использование ? в качестве встроенной нулевой проверки, еслисоответствующий атрибут не найден.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...