简体   繁体   中英

Simple Linq to XML Query Doesn't Work

I nominate me for village idiot.

Why doesn't this work:

foreach (XElement clientField in _clientXml.Descendants("row").Descendants())
{
    var newFieldName =
        from sourceField in _sourceEntries.Descendants("Field")
        where (string)sourceField.Attribute("n") == (string)clientField.Attribute("n")
        select new
            {
                FieldName = ((string) sourceField.Attribute("n")),
                AcordRef = ((string) sourceField.Attribute("m"))
             };
        foreach (var element in newFieldName)
        {
            Console.WriteLine("Field Name: {0}", 
            element.FieldName, element.AcordRef);
        }
}

My source XML files are loaded with XElement.Load(myFileName). In debug, clientField has an attribute n="Policy Number". The first element of _sourceEntries.Descendants("Field") also has an attribute n="Policy Number". Indeed, each element in _clientXml.Descendants("row").Descendants() has a matching row in _sourceEntries.Descendants("Field"). And, I know just enough to know that the select is lazy, so in debug I look at the Console.WriteLine block. No matter what I've tried, newFieldName is an empty set.

Just in case, here's the first element of the client file:

<Column_0 n="Policy Number">ABC000123</Column_0>

And, here's the fist element of the _sourceEntries collection:

<Field n="Policy Number" c="1" l="" s="" cd="" m="1805" f="" />

I know it's going to be something simple, but I just don't see what I'm doing wrong.

Thanks.

Randy

This accomplished what I ultimately needed to do:

foreach (var clientField in _clientXml.Descendants("row").Descendants())
    {
        foreach (var acordMapRef in
            from sourceEntry in _clientTemplate.Descendants("SourceEntries").Descendants("Field")
                where (string) clientField.Attribute("n") == (string) sourceEntry.Attribute("n")
                from acordMapRef in _clientTemplate.Descendants("Acord").Descendants("Field")
                where (string) sourceEntry.Attribute("m") == (string) acordMapRef.Attribute("id")
                select acordMapRef)
            {
                clientField.Attribute("n").Value = (string) acordMapRef.Attribute("n");
            }
    }

But, it's surely a candidate for ugliest code of the month. One thing I noticed in fooling around is that elements in an XElement tree don't seem to match to XElements in an IEnumerable collection. You might notice in the original code, above, I had an object _sourceEntries. This was a collection derived from _clientTemplate.Descendants("SourcEntries").Descendants("Field"). I would have thought that the two forms were essentially equivalent for my purposes, but apparently not. I'd appreciate somebody commenting on this issue.

Thanks folks!

Try changing:

where (string)sourceField.Attribute("n") == (string)clientField.Attribute("n")

To:

where sourceField.Attribute("n").Value == clientField.Attribute("n").Value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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