2013-03-20 162 views
0

我已經參考了XPathSelectElement select the second when there is more than oneXPath and XPathSelectElement。但這是一個不同的問題。基於其他元素值選擇元素

我有以下的XML。我需要找出與Sequence 2相對應的Message元素值(來自StatusDetail)。如果沒有序列2存在,它應該返回null。使用XPathSelectElement在C#中執行此操作的最佳方法是什麼?

注意:可以有任何數量的StatusDetail(或者根本沒有)的

注:StatusDetail元件可以是任何順序。我們需要在2

CODE

XDocument xDoc = XDocument.Parse(@" 
      <Status> 
      <StatusMsg> 
       <StatusType>INVOICE</StatusType> 
       <StatusCode>READYPAY</StatusCode> 
       <StatusTimestamp>2013-03-19T21:20:54Z</StatusTimestamp> 
       <StatusDetail> 
       <Sequence>1</Sequence> 
       <Message>.Document posted successfully </Message> 
       </StatusDetail> 
       <StatusDetail> 
       <Sequence>2 </Sequence> 
       <Message>Invoice is ready for pay</Message> 
       </StatusDetail> 
      </StatusMsg> 
      </Status> 
      "); 

var statusDetails = xDoc.XPathSelectElements(@"Status/StatusMsg/StatusDetail"); 

UPDATE

下面只查找值「2」是,我使用基於所選答案的解決方案

var statusDetails = xDoc.XPathSelectElements(@"Status/StatusMsg/StatusDetail/Sequence[text()=2]/../Message").FirstOrDefault(); 
if (statusDetails != null) 
{ 
    selectedMessage = statusDetails.Value; 
} 

回答

1
var statusDetails = xDoc.XPathSelectElements(@"Status/StatusMsg/StatusDetail/Sequence[text()=2]/../Message"); 

它使用text()通過其值和父選擇器/..選擇元素以從該元素返回到其父元素。

添加ToList()SingleOrDefault來枚舉結果並將其保存到列表或單個XElement對象中。

更新

的LINQ to XML查詢版本:

var results = from sd in xDoc.Root.Elements("StatusMsg").Elements("StatusDetail") 
       let s = sd.Element("Sequence") 
       where s != null && ((string)s).Trim() == "2" 
       select (string)sd.Element("Message"); 

,並與基於方法的查詢:

results = xDoc.Root.Elements("StatusMsg").Elements("StatusDetail") 
       .Select(sd => new { sd, s = sd.Element("Sequence") }) 
       .Where(x => x.s != null && ((string)x.s).Trim() == "2") 
       .Select(x => (string)x.sd.Element("Message")) 

您可以添加其他.Where(x => x != null)跳過null結果(它存在當有StatusDetailSeqience == 2,但是n Message元素。

+0

我測試過它和它的作品。你有什麼問題? – MarcinJuraszek 2013-03-20 08:47:56

+0

我不明白你。你如何嘗試在'XPathSelectElements'中應用'Root'?添加'ToList()'枚舉查詢並得到結果爲'List ' – MarcinJuraszek 2013-03-20 08:58:09

+0

以下是我正在使用的。它工作正常。 var statusDetails = xDoc.XPathSelectElements(@「Status/StatusMsg/StatusDetail/Sequence [text()= 2] /../ Message」)。FirstOrDefault(); – Lijo 2013-03-20 09:08:56

1

爲什麼不使用LINQ to XML:

var result = xDoc.Descendants("StatusDetail") 
      .Where(x => 
         { 
          var xElement = x.Element("Sequence"); 
          return xElement != null && xElement.Value.Trim() == "2"; 
         }) 
      .Select(x => (string)x.Element("Message")) 
      .SingleOrDefault(); 
+0

如果我們遇到一個沒有'Message'元素的'StatusDetail'元素(值爲2),它將失敗。有什麼建議麼? – Lijo 2013-03-20 07:04:36

+0

@Lijo:編輯--- – 2013-03-20 07:09:28

+2

你可以使用''(string)x.Element'來避免'(?:)'consurisal語句。不過,我認爲'XPath'在這種情況下更具可讀性。 – MarcinJuraszek 2013-03-20 07:12:02

相關問題