如何加入两个匿名类型的 IEnumerables?
How to Join two IEnumerables with anonymous types?
我正在使用 Linq-to-Xml 创建两个 IEnumerables
但我想将第二个列表的结果与第一个列表组合。当我使用 .Concat()
时,出现以下错误:
'IQueryable<>' does not contain a definition for 'Concat' and the best extension method overload 'ParallelEnumerable.Concat<>(ParallelQuery<>, IEnumerable<>)' requires a receiver of type 'ParallelQuery<>'
我要 .Concat()
的两个列表在这里:
var findingDetails = from f in element.Elements(ns + "Group")
select new
{
testID = (string)f.Attribute("id").Value,
title = (string)f.Element(ns + "title"),
idrefFD = (string)f.Element(ns + "Rule").Attribute("id").Value,
severity = (string)f.Element(ns + "Rule").Attribute("severity").Value,
description = (string)f.Element(ns + "Rule").Element(ns + "description"),
fixText = (string)f.Element(ns + "Rule").Element(ns + "fixtext")
};
var getStatus = from gs in element.Descendants(ns + "rule-result")
select new
{
idrefStatus = (string)gs.Attribute("idref").Value,
result = (string)gs.Element(ns + "result"),
dateTime = (string)gs.Attribute("time")
};
这里的 findingDetails
用法产生错误:
var combined = findingDetails.Concat(getStatus);
我想要得到的是一个 var
,其中包含 findingDetails
+ getStatus.result
和 getStatus.dateTime
中的所有内容。这就是为什么我只需要迭代一个 foreach()
循环来访问所有值,而不是使用嵌套的 foreach()
循环。
样本XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<cdf:Benchmark style="SCAP_1.1" resolved="1" id="RHEL_6_STIG" xsi:schemaLocation="http://checklists.nist.gov/xccdf/1.1 http://nvd.nist.gov/schema/xccdf-1.1.4.xsd http://cpe.mitre.org/dictionary/2.0 http://scap.nist.gov/schema/cpe/2.2/cpe-dictionary_2.2.xsd" xmlns:cdf="http://checklists.nist.gov/xccdf/1.1" xmlns:cpe="http://cpe.mitre.org/dictionary/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<cdf:status date="2016-04-22">accepted</cdf:status>
<cdf:title>Red Hat Enterprise Linux 6 Security Technical Implementation Guide</cdf:title>
<cdf:description>The Red Hat Enterprise Linux 6 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: disa.stig_spt@mail.mil.</cdf:description>
<cdf:notice id="terms-of-use"></cdf:notice>
<cdf:reference href="http://iase.disa.mil">
<dc:publisher>DISA</dc:publisher>
<dc:source>STIG.DOD.MIL</dc:source>
</cdf:reference>
<cdf:plain-text id="release-info">Release: 11 Benchmark Date: 22 Apr 2016</cdf:plain-text>
<cdf:platform idref="cpe:/o:redhat:enterprise_linux:6"></cdf:platform>
<cdf:version>1</cdf:version>
<cdf:Profile id="MAC-1_Classified">
<cdf:title>I - Mission Critical Classified</cdf:title>
</cdf:Profile>
<cdf:Value id="var_umask_for_daemons">
<cdf:title>daemon umask</cdf:title>
<cdf:description>Enter umask for daemons</cdf:description>
<cdf:value>022</cdf:value>
<cdf:value selector="022">022</cdf:value>
<cdf:value selector="027">027</cdf:value>
</cdf:Value>
<cdf:Group id="V-7055">
<cdf:title>APPNET0031 No Strong Name Verification</cdf:title>
<cdf:description><GroupDescription></GroupDescription></cdf:description>
<cdf:Rule weight="10.0" id="SV-7438r2_rule" severity="medium">
<cdf:version>APPNET0031</cdf:version>
<cdf:title>Digital signatures assigned to strongly named assemblies must be verified.</cdf:title>
<cdf:description><VulnDiscussion>A strong name consists of the assembly's identity, simple text name, version number, and culture information (if provided)—plus a public key and a digital signature. Strong names serve to identify the author of the code. If digital signatures used to sign strong name assemblies are not verified, any self signed code can be impersonated. This can lead to a loss of system integrity. </VulnDiscussion><FalsePositives></FalsePositives><FalseNegatives></FalseNegatives><Documentable>false</Documentable><Mitigations></Mitigations><SeverityOverrideGuidance></SeverityOverrideGuidance><PotentialImpacts></PotentialImpacts><ThirdPartyTools></ThirdPartyTools><MitigationControl></MitigationControl><Responsibility>System Administrator</Responsibility><IAControls>DCSL-1</IAControls></cdf:description>
<cdf:reference>
<dc:publisher>DISA</dc:publisher>
<dc:identifier>2030</dc:identifier>
<dc:type>DPMS Target</dc:type>
</cdf:reference>
<cdf:fixtext fixref="F-12596r7_fix">Use regedit to remove the values stored in Windows registry key hKLM\Software\Microsoft\StrongName\Verification. There should be no assemblies or hash values listed under this registry key. All assemblies must require strong name verification in a production environment. Strong name assemblies that do not require verification in a development or test environment must have documented approvals from the IAO.</cdf:fixtext>
<cdf:fix id="F-12596r7_fix"></cdf:fix>
<cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:2"></cdf:check-content-ref>
</cdf:check>
</cdf:Rule>
</cdf:Group>
<cdf:TestResult start-time="2016-07-20T11:59:59" version="1" test-system="cpe:/a:spawar:scc:4.1" end-time="2016-07-20T12:00:50" id="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-xccdf.xml---MAC-2_Classified-1">
<cdf:benchmark href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-xccdf.xml"></cdf:benchmark>
<cdf:organization>SPAWAR Systems Center Atlantic</cdf:organization>
<cdf:identity privileged="true" authenticated="true">CCSAdmin</cdf:identity>
<cdf:profile idref="MAC-2_Classified"></cdf:profile>
<cdf:target>hostname</cdf:target>
<cdf:target-address>192.168.1.000</cdf:target-address>
<cdf:target-facts>
<cdf:fact name="urn:scap:fact:asset:identifier:host_name" type="string">hostname</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:domain" type="string">.net</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:fqdn" type="string">hostname.net</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:os_name" type="string">Windows 7 Enterprise</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:os_service_pack" type="string">Service Pack 1</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:ipv4" type="string">192.168.1.000</cdf:fact>
</cdf:target-facts>
<cdf:platform idref="cpe:/a:microsoft:.net_framework:4.0"></cdf:platform>
<cdf:rule-result version="APPNET0031" time="2016-07-20T11:59:59" idref="SV-7438r2_rule" weight="10.0" severity="medium">
<cdf:result>pass</cdf:result>
<cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:2"></cdf:check-content-ref>
</cdf:check>
</cdf:rule-result>
<cdf:rule-result version="APPNET0046" time="2016-07-20T11:59:59" idref="SV-7444r3_rule" weight="10.0" severity="medium">
<cdf:result>fail</cdf:result>
<cdf:fix id="F-12602r12_fix"></cdf:fix>
<cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:15"></cdf:check-content-ref>
</cdf:check>
</cdf:rule-result>
</cdf:TestResult>
</cdf:Benchmark>
我更改了查询,现在它们看起来像这样:
var findingDetails = from f in element.Elements(ns + "Group")
select new
{
idrefStatus = (string)"",
result = (string)"",
dateTime = (string)"",
testID = (string)f.Attribute("id").Value,
title = (string)f.Element(ns + "title"),
idref = (string)f.Element(ns + "Rule").Attribute("id").Value,
severity = (string)f.Element(ns + "Rule").Attribute("severity").Value,
description = (string)f.Element(ns + "Rule").Element(ns + "description"),
fixText = (string)f.Element(ns + "Rule").Element(ns + "fixtext")
};
var getStatus = from gs in element.Descendants(ns + "rule-result")
select new
{
idrefStatus = (string)gs.Attribute("idref").Value,
result = (string)gs.Element(ns + "result"),
dateTime = (string)gs.Attribute("time"),
testID = (string)"",
title = (string)"",
idref = (string)"",
severity = (string)"",
description = (string)"",
fixText = (string)""
};
var combined = findingDetails.Concat(getStatus);
但现在输出看起来像这样
foreach (var cf in combined)
{
Console.WriteLine(cf.idref + ", " + cf.result);
}
SV-7438r2_rule,
SV-7444r3_rule,
SV-40966r1_rule,
SV-41075r1_rule,
, pass
, fail
, pass
, pass
然而,我正试图得到这样的东西:
SV-7438r2_rule, pass
SV-7444r3_rule, fail
SV-40966r1_rule, pass
SV-41075r1_rule, pass
如果两个匿名类型声明为具有完全相同的属性,则可以连接它们。
你不能连接两个不同的类型,但你可以将它们转换为 object
然后连接:
List<int> ints = new List<int>() { 1, 2, 3 };
List<string> strings = new List<string> { "a", "b", "c" };
ints.Cast<object>().Concat( strings.Cast<object>() );
从您的预期输出 ("Whereas, I'm trying to get something like this:...") 和您添加的数据来看,您正在寻找的似乎是 join
而不是 concat
列表(concat 会给你 n*m 条记录)
这似乎是您要找的东西:
XNamespace ns = "http://checklists.nist.gov/xccdf/1.1";
var findingDetails = (from f in XDocument.Load("data.xml").Descendants(ns + "Group")
let rule = f.Element(ns + "Rule")
select new
{
testID = (string)f.Attribute("id").Value,
title = (string)f.Element(ns + "title"),
idref = (string)rule.Attribute("id").Value,
severity = (string)rule.Attribute("severity").Value,
description = (string)rule.Element(ns + "description"),
fixText = (string)rule.Element(ns + "fixtext")
}).ToList();
var getStatus = (from gs in XDocument.Load("data.xml").Descendants(ns + "rule-result")
select new
{
idrefStatus = (string)gs.Attribute("idref").Value,
result = (string)gs.Element(ns + "result"),
dateTime = (string)gs.Attribute("time"),
}).ToList();
var result = (from d in findingDetails
join f in getStatus on d.idref equals f.idrefStatus
select new { d, f }).ToList();
如果您的 Group
没有匹配的 rule-result
,则使用 left join
代替
我正在使用 Linq-to-Xml 创建两个 IEnumerables
但我想将第二个列表的结果与第一个列表组合。当我使用 .Concat()
时,出现以下错误:
'IQueryable<>' does not contain a definition for 'Concat' and the best extension method overload 'ParallelEnumerable.Concat<>(ParallelQuery<>, IEnumerable<>)' requires a receiver of type 'ParallelQuery<>'
我要 .Concat()
的两个列表在这里:
var findingDetails = from f in element.Elements(ns + "Group")
select new
{
testID = (string)f.Attribute("id").Value,
title = (string)f.Element(ns + "title"),
idrefFD = (string)f.Element(ns + "Rule").Attribute("id").Value,
severity = (string)f.Element(ns + "Rule").Attribute("severity").Value,
description = (string)f.Element(ns + "Rule").Element(ns + "description"),
fixText = (string)f.Element(ns + "Rule").Element(ns + "fixtext")
};
var getStatus = from gs in element.Descendants(ns + "rule-result")
select new
{
idrefStatus = (string)gs.Attribute("idref").Value,
result = (string)gs.Element(ns + "result"),
dateTime = (string)gs.Attribute("time")
};
这里的 findingDetails
用法产生错误:
var combined = findingDetails.Concat(getStatus);
我想要得到的是一个 var
,其中包含 findingDetails
+ getStatus.result
和 getStatus.dateTime
中的所有内容。这就是为什么我只需要迭代一个 foreach()
循环来访问所有值,而不是使用嵌套的 foreach()
循环。
样本XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<cdf:Benchmark style="SCAP_1.1" resolved="1" id="RHEL_6_STIG" xsi:schemaLocation="http://checklists.nist.gov/xccdf/1.1 http://nvd.nist.gov/schema/xccdf-1.1.4.xsd http://cpe.mitre.org/dictionary/2.0 http://scap.nist.gov/schema/cpe/2.2/cpe-dictionary_2.2.xsd" xmlns:cdf="http://checklists.nist.gov/xccdf/1.1" xmlns:cpe="http://cpe.mitre.org/dictionary/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<cdf:status date="2016-04-22">accepted</cdf:status>
<cdf:title>Red Hat Enterprise Linux 6 Security Technical Implementation Guide</cdf:title>
<cdf:description>The Red Hat Enterprise Linux 6 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: disa.stig_spt@mail.mil.</cdf:description>
<cdf:notice id="terms-of-use"></cdf:notice>
<cdf:reference href="http://iase.disa.mil">
<dc:publisher>DISA</dc:publisher>
<dc:source>STIG.DOD.MIL</dc:source>
</cdf:reference>
<cdf:plain-text id="release-info">Release: 11 Benchmark Date: 22 Apr 2016</cdf:plain-text>
<cdf:platform idref="cpe:/o:redhat:enterprise_linux:6"></cdf:platform>
<cdf:version>1</cdf:version>
<cdf:Profile id="MAC-1_Classified">
<cdf:title>I - Mission Critical Classified</cdf:title>
</cdf:Profile>
<cdf:Value id="var_umask_for_daemons">
<cdf:title>daemon umask</cdf:title>
<cdf:description>Enter umask for daemons</cdf:description>
<cdf:value>022</cdf:value>
<cdf:value selector="022">022</cdf:value>
<cdf:value selector="027">027</cdf:value>
</cdf:Value>
<cdf:Group id="V-7055">
<cdf:title>APPNET0031 No Strong Name Verification</cdf:title>
<cdf:description><GroupDescription></GroupDescription></cdf:description>
<cdf:Rule weight="10.0" id="SV-7438r2_rule" severity="medium">
<cdf:version>APPNET0031</cdf:version>
<cdf:title>Digital signatures assigned to strongly named assemblies must be verified.</cdf:title>
<cdf:description><VulnDiscussion>A strong name consists of the assembly's identity, simple text name, version number, and culture information (if provided)—plus a public key and a digital signature. Strong names serve to identify the author of the code. If digital signatures used to sign strong name assemblies are not verified, any self signed code can be impersonated. This can lead to a loss of system integrity. </VulnDiscussion><FalsePositives></FalsePositives><FalseNegatives></FalseNegatives><Documentable>false</Documentable><Mitigations></Mitigations><SeverityOverrideGuidance></SeverityOverrideGuidance><PotentialImpacts></PotentialImpacts><ThirdPartyTools></ThirdPartyTools><MitigationControl></MitigationControl><Responsibility>System Administrator</Responsibility><IAControls>DCSL-1</IAControls></cdf:description>
<cdf:reference>
<dc:publisher>DISA</dc:publisher>
<dc:identifier>2030</dc:identifier>
<dc:type>DPMS Target</dc:type>
</cdf:reference>
<cdf:fixtext fixref="F-12596r7_fix">Use regedit to remove the values stored in Windows registry key hKLM\Software\Microsoft\StrongName\Verification. There should be no assemblies or hash values listed under this registry key. All assemblies must require strong name verification in a production environment. Strong name assemblies that do not require verification in a development or test environment must have documented approvals from the IAO.</cdf:fixtext>
<cdf:fix id="F-12596r7_fix"></cdf:fix>
<cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:2"></cdf:check-content-ref>
</cdf:check>
</cdf:Rule>
</cdf:Group>
<cdf:TestResult start-time="2016-07-20T11:59:59" version="1" test-system="cpe:/a:spawar:scc:4.1" end-time="2016-07-20T12:00:50" id="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-xccdf.xml---MAC-2_Classified-1">
<cdf:benchmark href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-xccdf.xml"></cdf:benchmark>
<cdf:organization>SPAWAR Systems Center Atlantic</cdf:organization>
<cdf:identity privileged="true" authenticated="true">CCSAdmin</cdf:identity>
<cdf:profile idref="MAC-2_Classified"></cdf:profile>
<cdf:target>hostname</cdf:target>
<cdf:target-address>192.168.1.000</cdf:target-address>
<cdf:target-facts>
<cdf:fact name="urn:scap:fact:asset:identifier:host_name" type="string">hostname</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:domain" type="string">.net</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:fqdn" type="string">hostname.net</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:os_name" type="string">Windows 7 Enterprise</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:os_service_pack" type="string">Service Pack 1</cdf:fact>
<cdf:fact name="urn:scap:fact:asset:identifier:ipv4" type="string">192.168.1.000</cdf:fact>
</cdf:target-facts>
<cdf:platform idref="cpe:/a:microsoft:.net_framework:4.0"></cdf:platform>
<cdf:rule-result version="APPNET0031" time="2016-07-20T11:59:59" idref="SV-7438r2_rule" weight="10.0" severity="medium">
<cdf:result>pass</cdf:result>
<cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:2"></cdf:check-content-ref>
</cdf:check>
</cdf:rule-result>
<cdf:rule-result version="APPNET0046" time="2016-07-20T11:59:59" idref="SV-7444r3_rule" weight="10.0" severity="medium">
<cdf:result>fail</cdf:result>
<cdf:fix id="F-12602r12_fix"></cdf:fix>
<cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:15"></cdf:check-content-ref>
</cdf:check>
</cdf:rule-result>
</cdf:TestResult>
</cdf:Benchmark>
我更改了查询,现在它们看起来像这样:
var findingDetails = from f in element.Elements(ns + "Group")
select new
{
idrefStatus = (string)"",
result = (string)"",
dateTime = (string)"",
testID = (string)f.Attribute("id").Value,
title = (string)f.Element(ns + "title"),
idref = (string)f.Element(ns + "Rule").Attribute("id").Value,
severity = (string)f.Element(ns + "Rule").Attribute("severity").Value,
description = (string)f.Element(ns + "Rule").Element(ns + "description"),
fixText = (string)f.Element(ns + "Rule").Element(ns + "fixtext")
};
var getStatus = from gs in element.Descendants(ns + "rule-result")
select new
{
idrefStatus = (string)gs.Attribute("idref").Value,
result = (string)gs.Element(ns + "result"),
dateTime = (string)gs.Attribute("time"),
testID = (string)"",
title = (string)"",
idref = (string)"",
severity = (string)"",
description = (string)"",
fixText = (string)""
};
var combined = findingDetails.Concat(getStatus);
但现在输出看起来像这样
foreach (var cf in combined)
{
Console.WriteLine(cf.idref + ", " + cf.result);
}
SV-7438r2_rule,
SV-7444r3_rule,
SV-40966r1_rule,
SV-41075r1_rule,
, pass
, fail
, pass
, pass
然而,我正试图得到这样的东西:
SV-7438r2_rule, pass
SV-7444r3_rule, fail
SV-40966r1_rule, pass
SV-41075r1_rule, pass
如果两个匿名类型声明为具有完全相同的属性,则可以连接它们。
你不能连接两个不同的类型,但你可以将它们转换为 object
然后连接:
List<int> ints = new List<int>() { 1, 2, 3 };
List<string> strings = new List<string> { "a", "b", "c" };
ints.Cast<object>().Concat( strings.Cast<object>() );
从您的预期输出 ("Whereas, I'm trying to get something like this:...") 和您添加的数据来看,您正在寻找的似乎是 join
而不是 concat
列表(concat 会给你 n*m 条记录)
这似乎是您要找的东西:
XNamespace ns = "http://checklists.nist.gov/xccdf/1.1";
var findingDetails = (from f in XDocument.Load("data.xml").Descendants(ns + "Group")
let rule = f.Element(ns + "Rule")
select new
{
testID = (string)f.Attribute("id").Value,
title = (string)f.Element(ns + "title"),
idref = (string)rule.Attribute("id").Value,
severity = (string)rule.Attribute("severity").Value,
description = (string)rule.Element(ns + "description"),
fixText = (string)rule.Element(ns + "fixtext")
}).ToList();
var getStatus = (from gs in XDocument.Load("data.xml").Descendants(ns + "rule-result")
select new
{
idrefStatus = (string)gs.Attribute("idref").Value,
result = (string)gs.Element(ns + "result"),
dateTime = (string)gs.Attribute("time"),
}).ToList();
var result = (from d in findingDetails
join f in getStatus on d.idref equals f.idrefStatus
select new { d, f }).ToList();
如果您的 Group
没有匹配的 rule-result
,则使用 left join
代替