XML到LINQ ElementAtOrDefault(x).elements表示不存在的索引

时间:2014-08-12 17:33:30

标签: xml vb.net linq linq-to-xml

我有一个问题在我需要在获得elementAtOrDefault方法之后拉出一个元素。我很确定我想要做的事情也可以用其他方式实现,也许我只是不知道。但是在LINQ查询中我正在尝试

Dim extractDetails = From GradScoreRows In doc.Root.Descendants(ns + "gradeOr") _
        Select New RecordScoreDetails With _
        { _
        .Result = GradScoreRows .Descendants(ns + "score").Elements(ns + "results").Value, _
        .ResultComment = GradScoreRows .Descendants(ns + "score").Elements(ns + "resultComment").Value, _
        .ImpactedScore = GradScoreRows .Descendants(ns + "score").Elements(ns + "ImpactedScore").Value, _
        .SubjectACode = GradScoreRows .Descendants(ns + "factors").Descendants(ns + "factor").ElementAtOrDefault(0).Elements(ns + "code").Value, _
        .SubjectARank = GradScoreRows .Descendants(ns + "factors").Descendants(ns + "factor").ElementAtOrDefault(1).Elements(ns + "rank").Value, _
        }

我想要查询的XML代码段是:

<gradeOr>
    <score>
           <results>Passed</results>
           <resultsComment>some comment</resultsComment>
           <impactedScore>Something impacted Score</impactedScore>
           <factors>
              <factor>
                  <code>A</code>
                  <rank>20</rank>
               </factor>
              <factor>
                   <code>B</code>
                   <rank>20</rank>
              </factor>
           </factors>
    </score>
</gradeOr>

问题是因素部分可能不会出现在我收到的每个XML中。我该如何处理这种情况?

我已经尝试过使用没有默认值的ElementsAt(x),显然我遇到了某个场景的索引是我们范围的问题,当我使用默认情况下我遇到的对象引用未设置为对象问题的实例。

1 个答案:

答案 0 :(得分:1)

可能有更优雅的方式,但有一种方式是这样的:

Dim extractDetails =
    From grade In doc...<gradeOr> 
    Let subjA = (From subj In grade.<score>.<factors>.<factor>).FirstOrDefault()
    Select New With {
        .Result = grade.<score>.<results>.Value,
        .ResultComment = grade.<score>.<resultsComment>.Value,
        .ImpactedScore = grade.<score>.<impactedScore>.Value,
        .SubjectACode = If(subjA IsNot Nothing, subjA.<code>.Value, Nothing),
        .SubjectARank = If(subjA IsNot Nothing, subjA.<rank>.Value, Nothing)
    }

这使用子查询查找第一个<factor>(如果有),并检查在填充属性时是否找到了。我对重复的If()语句不满意,但它似乎运作正常。

您需要进行调整以适应您的类和/或命名空间,因为我没有这些信息。我还不完全确定这是否会获得SubjectACode/Rank属性的正确元素,因为我认为您的代码会从不同的<factor>元素中提取它们,而且我不确定示例XML中与SubjectA相关的A值。请澄清我是否错过了什么。