繁体   English   中英

基于属性名称/值对创建通用xml linq搜索

[英]Creating a generic xml linq search based on attribute name/value pairs

我有一组正在使用的功能,其中一个功能是解析XML文件,并返回与我具有的基于属性的条件匹配的元素。

这是我必须使用的XML的示例:

 <rs:insert>
<z:row Inst='AM5001' Event='EventA' HostName='HostA' EventType='NORMAL' TXID='0000003327'/>
<z:row Inst='AM5001' Event='EventB' HostName='HostB' EventType='NORMAL' TXID='0000011173'/>
<z:row Inst='AM4067' Event='EventA' HostName='HostA' EventType='NORMAL' TXID='0000011175'/>
<z:row Inst='AM5546' Event='EventC' HostName='HostC' EventType='NORMAL' TXID='0000011177'/>
<z:row Inst='AM4567' Event='EventQ' HostName='HostD' EventType='NORMAL' TXID='0000011593'/>

这是到目前为止的内容的摘要:

internal protected IEnumerable<XElement> GetElement(XDocument oXMLDoc
        , List<KeyValuePair<string, string>> SearchCriteria)
    {
        var vElementQuery = oXMLDoc.Elements()
            .Where(e => SearchCriteria.ForEach(sc => e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper()))
            .Select(e => e);

        foreach (var xElement in vElementQuery)
        {
            yield return xElement;
        }
    }

我在vElementQuery的where子句中遇到错误:

只能将赋值,调用,递增,递减,等待和新对象表达式用作语句

为简单起见,我将基于Inst和Event进行查询,但有时我也需要基于主机名和Eventtype。

基本上,我不知道需要匹配多少个属性条件,因此我想将它们添加为列表或数组,以为KeyValuePair会很有用,因为它会给我名称和比较(值)我需要的。

感谢您的帮助。

Where需要一个谓词:一个函数,该函数接受e (在这种情况下为XElement )并返回bool

相反,您尝试返回SearchCriteria.ForEach()的结果,该结果返回void 它所做的只是遍历集合并为每个项目调用一个void lambda。 因此,您不能将其用作谓词的主体。 解决此问题后,这将是您的下一个问题,但是相同的修复可以同时解决这两个问题。

.Where(e => 
    SearchCriteria.ForEach(sc => 
        e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper()
    )
)

因为ForEach返回void ,所以需要一个lambda来返回void 函数的主体必须是一个语句。 在lambda中,如果返回类型不是void ,并且主体是表达式,则返回该表达式的结果-将其称为隐式return语句。 但是这里的返回值是空的-由ForEach的参数类型确定

public void ForEach(
    Action<T> action
)

Action<T>有一个参数,没有返回类型。 无论编译器使用哪种推论规则,都将在结果中假定您要编写一个无效的lambda,而不是要给ForEach一个谓词。

这是您要给它的lambda的主体:

e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper()

没有编译器在其前面提供隐式return ,那不是语句。 这是一种表达。 声明,这不是合法的C#。 尝试编译此:

1 != 2;

同样的错误。 C或Perl不在乎,但C#会。

我认为您可能想要Any而不是ForEach

.Where(e => 
    SearchCriteria.Any(sc => 
        e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper()
    )
)

也就是说,返回任何搜索条件与其属性匹配的任何e Any取一个谓词并返回bool ,从而修复了两个错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM