代码之家  ›  专栏  ›  技术社区  ›  Kinyanjui Kamau

使用LINQ查询从XML提取值

  •  0
  • Kinyanjui Kamau  · 技术社区  · 6 年前

    不熟悉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();
    

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

    4 回复  |  直到 6 年前
        1
  •  2
  •   Markus    6 年前

    您需要访问 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 (没有尾随的s),您只访问单个元素而不是多个元素,因此您的结果只包含第一个元素的值。

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

        2
  •  0
  •   Aparna Gadgil    6 年前

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

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

        3
  •  0
  •   Gauravsa    6 年前

    您可以使用 SelectMany 在Linq。

    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在这里拨弄: https://dotnetfiddle.net/IKd7go

        4
  •  0
  •   Kevin    6 年前

    作为另一种选择,这对我来说似乎更容易:

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