У меня есть 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#, и я уверен, что существуют другие лучшие формы для доступа к этому типу данных.
Не могли бы вы помочь мне получить доступ к этим данным по типу?
Я не могу заставить ваш XML анализировать! Вы уверены, что это действительно так?
@ Wheels73 недействителен. Обратите внимание на незакрытые элементы.
@SebastianHofmann - Ах да ... Мне еще рано! Ваше здоровье!
Вы уверены, что <RoutePoints> не имеет пространства имен (по умолчанию)? Что вам сообщает отладчик? Также вы не показали, как у вас появился i:
XML слишком велик, я использовал псевдокод для упрощения. Символ «+» указывает на то, что раздел может быть расширен (Подробнее).





Если вы используете 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")
{
}
}
}
Обратите внимание на использование ? в качестве встроенной нулевой проверки, если соответствующий атрибут не найден.
Когда указатель находится в: <a: anyType z: Ref = "349" i: nil = "true" /> и проверьте FirstOrDefault () ?. Value == "RoutePointTakeOff", произойдет сбой программы, поскольку исключение NullReferenceException было необработанным.
Нет, если у нас нет других файлов xml. Оператор ? не кидает.
Да не пользовался? оператор. Но не работает это для меня.
Попробуйте следующее:
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();
Это решение берет только атрибуты файла XML и помещает его в список, не так ли? Мне нужно взять элемент, информация, которую мне нужно обработать, находится внутри элементов. Например, внутри RoutePoint мне нужно инициализировать некоторые атрибуты значениями, которые содержат. Внутри RoutePointTakeOff мне нужно выполнить некоторые алгоритмы. Проблема в том, что мне нужно выполнять разные функции в зависимости от раздела, в котором указатель.
Вы можете добавить свой код в мой. Используйте foreach (маршрут var в результатах) {}. Вам нужно будет проверить значение null. Значения будут id, _ref, type. Вы не включили в свой образец значение какого-либо элемента. Если есть элемент, добавьте value = (string) x как другую строку.
Попробуй это
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; }
}
после этого вы можете отсортировать группу данных по имени.
если вы используете этот код, вы не ограничены в названии атрибута. удачи.
Я отлаживал и наконец нашел ошибку ...
Я оценивал атрибут «тип», которого нет в строках 4-5. Это привело к ошибке. Более конкретно:
NullReferenceException was Unhandled
В конце концов, я использую нулевой элемент управления, и теперь он работает.
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
}
}
}
«Сбой моей программы» - что именно происходит? Выдается исключение?