我有一个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内部,我需要执行一些算法。问题是我需要根据where指针所在的部分执行不同的功能。
我是C#的新编程人员,并且可以肯定存在另一种更好的形式来访问此类数据。
您能帮助我按类型访问此数据吗?
答案 0 :(得分:2)
尝试以下操作:
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();
答案 1 :(得分:1)
如果您使用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")
{
}
}
}
请注意,如果找不到匹配的属性,请使用?
作为内联null检查。
答案 2 :(得分:1)
尝试这个
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; }
}
在此之后,您可以按名称对数据组进行排序。
如果使用此代码,则不受属性名称的限制。 祝你好运。
答案 3 :(得分:0)
我正在调试,最后发现错误...
我正在评估属性“类型”,该属性在第4-5行中不存在。这导致了错误。更具体地说:
未处理NullReferenceException
毕竟我使用的是null控件,现在它可以工作了。
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
}
}
}