我已提及XPathSelectElement select the second when there is more than one和XPath and XPathSelectElement。但这是一个不同的问题。
我有以下xml。我需要找出与Sequence 2对应的Message元素值(来自StatusDetail)。如果没有序列2存在,它应该返回null。使用XPathSelectElement
在C#中执行此操作的最佳方法是什么?
注意:可以有任意数量的StatusDetail(或根本不存在)
注意:StatusDetail元素可以按任何顺序排列。我们只需要查看2中的值“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");
更新
以下是我根据所选答案使用的解决方案
var statusDetails = xDoc.XPathSelectElements(@"Status/StatusMsg/StatusDetail/Sequence[text()=2]/../Message").FirstOrDefault();
if (statusDetails != null)
{
selectedMessage = statusDetails.Value;
}
答案 0 :(得分: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
结果(当StatusDetail
有Seqience == 2
但没有Message
元素时,该结果就会存在。
答案 1 :(得分: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();