简体   繁体   中英

XDocument C# Join

I have to use joins for the below xml using XDocument

<Books>
    <Book>
        <Name id="1">Test</Name>
        <CardNo>1234</CardNo>
    </Book>
    <Book>
        <Name id="1">Test</Name>
        <CardNo>5678</CardNo>
    </Book>
    <Library>
        <RackNo>4</RackNo>
        <SampleData>Hello</SampleData>
        <CardNo>1234</CardNo>
    </Library>
    <Library>
        <RackNo>5</RackNo>
        <SampleData>John</SampleData>
        <CardNo>5678</CardNo>
    </Library>
</Books>

In the above sample I need to join the CardNo but they are present under two different Records.. ie Library and Book. I'm using this code but the join doesn't work for XDocument. Any suggestions please?

 var bookRecords = from c in doc.Element("Books").Element("Book")
                   select new { bookCardNo = c.Attribute("CardNo").Value }

var LibraryRecords = from d in doc.Element("Books").Element("Library")
                   select new { libCardNo = d.Attribute("CardNo").Value }

var groupedRecords = 
    from br in bookRecords
    join lr in LibraryRecords 
    on br.bookCardNo equals lr.libCardNo
    select new { rackno = lr.Element("RackNo").Value }

First, you're querying for multiple elements, so you want Elements and not Element . Element will only return the first item, so your LINQ expression won't compile.

Secondly, there is no attribute called CardNo - CardNo is an element .

And finally, LibraryRecords will contain a bunch of anonymous objects. If you want to access RackNo , or any other property, you will need to include their values as a property of that object.

var bookRecords =
    from book in doc.Elements("Books").Elements("Book")
    select new
    {
        Name = (string) book.Element("Name"),
        CardNo = (string) book.Element("CardNo")
    };

var libraryRecords =
    from lib in doc.Elements("Books").Elements("Library")
    select new
    {
        CardNo = (string) lib.Element("CardNo"),
        RackNo = (string) lib.Element("RackNo"),
    };

var groupedRecords =
    from br in bookRecords
    join lr in libraryRecords
    on br.CardNo equals lr.CardNo
    select new
    {
        br.Name,
        lr.RackNo
    };

See this fiddle for a demo.

Libraries are at the same level than books according to the xml schema you show, it'll be easier if you use Descendants method, and instead of use Attribute , use Element because CardNo is not an attribute in both cases:

var bookRecords = from c in doc.Descendants("Book")
                   select new { bookCardNo = c.Element("CardNo").Value };

var LibraryRecords = from d in doc.Descendants("Library")
                     select new { libCardNo = d.Element("CardNo").Value,
                                  rackno = d.Element("RackNo").Value  };

var groupedRecords = 
    from br in bookRecords
    join lr in LibraryRecords 
    on br.bookCardNo equals lr.libCardNo
    select lr.rackno;

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