C# 使用linq查询从XML中提取值
linq和XML新手,正在寻找返回值的方法C# 使用linq查询从XML中提取值,c#,xml,linq,C#,Xml,Linq,linq和XML新手,正在寻找返回值的方法 作为一个列表,然后将这些值连接到一个字符串中 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'> <C
作为一个列表,然后将这些值连接到一个字符串中
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>
但这只返回第一个值“Duplicate File”。如何解决此问题?您需要访问
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();
通过使用元素
(不带尾随的s),您只能访问单个元素而不是多个元素,因此您的结果只包含第一个元素的值
通过使用而不是
Select
可以从子枚举返回多个元素。您需要访问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();
通过使用元素
(不带尾随的s),您只能访问单个元素而不是多个元素,因此您的结果只包含第一个元素的值
通过使用而不是
Select
可以从子枚举返回多个元素。在代码中,r.Element
将始终返回集合的第一个元素。
相反,尝试使用r.Elements
,这将返回“AddtlInf”元素的集合
有关这方面的详细信息,请查看此 在代码中,
r.Element
将始终返回集合的第一个元素。
相反,尝试使用r.Elements
,这将返回“AddtlInf”元素的集合
有关这方面的详细信息,请查看此 您可以在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 fiddle此处:您可以在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 fiddle这里:作为一种选择,这对我来说似乎更容易:
var list = doc.XPathSelectElements
("Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/StsRsnInf/AddtlInf")
.Select(n => n.Value);
作为一种选择,我觉得这更容易:
var list = doc.XPathSelectElements
("Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/StsRsnInf/AddtlInf")
.Select(n => n.Value);
简单而有意义。简单而有意义。