0

当有多个XPath 和 XPathSelectElement时,我已经提到XPathSelectElement 选择第二个。但这是一个不同的问题。

我有以下 xml。我需要找出对应于序列 2 的 Message 元素值(来自 StatusDetail)。如果不存在序列 2,它应该返回 null。在 C# 中使用 执行此操作的最佳方法是什么XPathSelectElement

注意:可以有任意数量的 StatusDetail(或根本没有)

注意:StatusDetail 元素可以按任何顺序排列。我们只需要在 2 中寻找值“2”

代码

 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;
}
4

2 回答 2

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结果(当有StatusDetailwith时存在Seqience == 2,但没有Message元素。

于 2013-03-20T06:44:34.493 回答
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();
于 2013-03-20T06:50:05.507 回答