【问题标题】:LINQ to XML selecting elements similar to SQL IN clauseLINQ to XML 选择类似于 SQL IN 子句的元素
【发布时间】:2019-03-06 21:00:46
【问题描述】:

我有一些包含付款信息的 XML,其中包括付款被应用到的发票的详细信息。例如,我想使用 LINQ to XML 仅收集适用于某些发票 (111,222,333) 的付款。如果是 SQL,我可以使用 IN (111,222,333) 关键字,但我不确定如何在 LINQ 中执行相同操作。

<Payment>
    <PaymentId>1</PaymentId>
    <Total>50</Total>
    <Invoice>
        <Id>111</Id>
        <Amount>20</Amount>
    </Invoice>
    <Invoice>
        <Id>555</Id>
        <Amount>30</Amount>
    </Invoice>
</Payment>
<Payment>
    <PaymentId>2</PaymentId>
    <Total>20</Total>
    <Invoice>
        <Id>222</Id>
        <Amount>20</Amount>
    </Invoice>
</Payment>
<Payment>
    <PaymentId>3</PaymentId>
    <Total>80</Total>
    <Invoice>
        <Id>888</Id>
        <Amount>80</Amount>
    </Invoice>
</Payment>

LINQ

var result = xml.Select(x => x.Element("Payment"))
               Where(x => x.Element("Id").Value.Contains("111","222","333"))

在本例中,我想选择“PaymentId 1”和“PaymentId 2”,因为它们适用于 ID 匹配 111、222 或 333 的发票。

【问题讨论】:

    标签: c# linq-to-xml linq-method-syntax


    【解决方案1】:

    您可以对这些知名 ID 的列表进行匹配/相交。

    List<string> ids = new List<string> { "111", "222", "333" };
    
    var result = xml
        .Elements("Payment")
        .Where(p => {
            var invoiceIds = p.Elements("Invoice").Elements("Id").Select(o => o.Value);
            return ids.Intersect(invoiceIds).Any();
        }
    );
    

    完整代码和NetFiddle


    const string XML = @"
        <root>
            <Payment>
                <PaymentId>1</PaymentId>
                <Total>50</Total>        
                <Invoice>
                    <Id>555</Id>
                    <Amount>30</Amount>
                </Invoice>
                <Invoice>
                    <Id>111</Id>
                    <Amount>30</Amount>
                </Invoice>
            </Payment>
            <Payment>
                <PaymentId>2</PaymentId>
                <Total>20</Total>
                <Invoice>
                    <Id>222</Id>
                    <Amount>20</Amount>
                </Invoice>
            </Payment>
            <Payment>
                <PaymentId>3</PaymentId>
                <Total>80</Total>
                <Invoice>
                    <Id>888</Id>
                    <Amount>80</Amount>
                </Invoice>
            </Payment>
        </root>
        ";
    
    XElement xml = XElement.Parse(XML);
    List<string> ids = new List<string> { "111", "222", "333" };
    
    var result = xml
        .Elements("Payment")
        .Where(p => {
            var invoiceIds = p.Elements("Invoice").Elements("Id").Select(o => o.Value);
            return ids.Intersect(invoiceIds).Any();
            }
        );
    
    foreach (var item in result)
    {
        Console.WriteLine("PaymentId: {0}", (string)item.Element("PaymentId"));
    }
    

    【讨论】:

    • 我明白了.. 所以我需要在已知 Id 的集合中找到 Id 元素值。我正以相反的方式去做..它没有用!谢谢!
    • 当我尝试这个时,我在ids 列表中得到一个Object reference not set to an instance of an object 错误。
    • @webworm 做了改进,没有注意到一次付款可以有多个 invoice-id。
    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2010-10-25
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多