【问题标题】:Extract values from XML with linq query使用 linq 查询从 XML 中提取值
【发布时间】:2018-11-30 09:44:27
【问题描述】:

刚接触 linq 和 XML,正在寻找一种将
<AddtlInf></AddtlInf> 的值作为列表返回的方法,然后我会将这些值连接到单个字符串。

下面的 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Document xmlns='urn:iso:std:iso:20022:tech:xsd:pain.002.001.03' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <CstmrPmtStsRpt>
    <GrpHdr>
      <MsgId>21233519</MsgId>
      <CreDtTm>2018-11-29T09:28:00</CreDtTm>
      <InitgPty>
        <Nm>Standard Bank SA</Nm>
        <Id>
          <OrgId>
            <BICOrBEI>SBZAZAJJXXX</BICOrBEI>
          </OrgId>
        </Id>
      </InitgPty>
    </GrpHdr>
    <OrgnlGrpInfAndSts>
      <OrgnlMsgId>Domestic Base-612742-300749</OrgnlMsgId>
      <OrgnlMsgNmId>PAIN.001.001.03</OrgnlMsgNmId>
      <OrgnlCreDtTm>2018-11-29T12:23:06</OrgnlCreDtTm>
      <OrgnlNbOfTxs>1</OrgnlNbOfTxs>
      <OrgnlCtrlSum>17500.00</OrgnlCtrlSum>
      <GrpSts>RJCT</GrpSts>
      <StsRsnInf>
        <Rsn>
          <Cd>NARR</Cd>
        </Rsn>
        <AddtlInf>Duplicate File</AddtlInf>
        <AddtlInf>Error: 6789</AddtlInf>
        <AddtlInf>Not Processed</AddtlInf>
      </StsRsnInf>
    </OrgnlGrpInfAndSts>
  </CstmrPmtStsRpt>
</Document>

到目前为止我有:

var info = doc.Descendants(ns + "CstmrPmtStsRpt")
           .Descendants(ns + "OrgnlGrpInfAndSts")
           .Descendants(ns + "StsRsnInf")                                       
           .Select(r => new
           {
                Info = r.Element(ns + "AddtlInf").Value                                          
           }).ToList();

但这只会返回“重复文件”,即第一个值。我该如何解决这个问题?

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    你需要访问StsRsnInf的子元素:

    var info = doc.Descendants(ns + "CstmrPmtStsRpt")
                .Descendants(ns + "OrgnlGrpInfAndSts")
                .Descendants(ns + "StsRsnInf")                                       
                .SelectMany(r => r.Elements(ns + "AddtlInf").Select(s => new
                {
                  Info = s.Value
                })).ToList();
    

    通过使用Element(不带尾随),您只能访问单个元素而不是多个元素,因此您的结果只包含第一个元素的值。

    通过使用SelectMany 而不是Select,您可以从子枚举中返回多个元素。

    【讨论】:

    • 简单而有意义。
    【解决方案2】:

    在您的代码中,r.Element 将始终返回集合的第一个元素。 而是尝试使用r.Elements,它将返回“AddtlInf”元素的集合。

    有关此的详细信息,请查看link!

    【讨论】:

      【解决方案3】:

      您可以在 Linq 中使用 SelectMany。

      var result = (string)xdoc.Descendants("member")
                               .FirstOrDefault(x => (string)x.Element("name") == "responseCode")
                               ?.Element("value");
      
          var info = xdoc.Descendants("CstmrPmtStsRpt")
         .Descendants("OrgnlGrpInfAndSts")
         .Descendants("StsRsnInf")                                       
         .SelectMany(r=> r.Descendants("AddtlInf")).ToList();
         Console.WriteLine(info.Count); // prints 3.
      

      Dotnet fiddle:https://dotnetfiddle.net/IKd7go

      【讨论】:

        【解决方案4】:

        作为替代方案,这对我来说似乎更容易:

        var list = doc.XPathSelectElements
                        ("Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/StsRsnInf/AddtlInf")
                        .Select(n => n.Value);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-04
          • 1970-01-01
          • 2021-04-07
          相关资源
          最近更新 更多