Query XDocument with LINQ to Return List

I have an xml String as so (shortened to only 2 Rows for ease of Testing ):

<?xml version="1.0" encoding="utf-8"?>
<DataTable Uid="DT_RetRes">
  <Rows>
    <Row>
      <Cells>
        <Cell>
          <ColumnUid>AVAIL</ColumnUid>
          <Value>N</Value>
        </Cell>
        <Cell>
          <ColumnUid>ItemCode</ColumnUid>
          <Value>PRODUCTID123#</Value>
        </Cell>
        <Cell>
          <ColumnUid>Dscription</ColumnUid>
          <Value>Basic Product 1 with hash</Value>
        </Cell>
        <Cell>
          <ColumnUid>U_JOW_CMNT</ColumnUid>
          <Value></Value>
        </Cell>
      </Cells>
    </Row>
    <Row>
      <Cells>
        <Cell>
          <ColumnUid>AVAIL</ColumnUid>
          <Value>Y</Value>
        </Cell>
        <Cell>
          <ColumnUid>ItemCode</ColumnUid>
          <Value>PRODUCTID234</Value>
        </Cell>
        <Cell>
          <ColumnUid>Dscription</ColumnUid>
          <Value>Basic Product 2 no hash</Value>
        </Cell>
        <Cell>
          <ColumnUid>U_JOW_CMNT</ColumnUid>
          <Value></Value>
        </Cell>
      </Cells>
    </Row>
</Rows>
</DataTable>

I am trying to query the Xdocument to return a list of all ItemCode Values where the Value of AVAIl is Y

My code Currently is as follows:

Dim xdoc As XDocument = XDocument.Parse(xmlString)

Dim result = xdoc.Elements("Rows").
Where(Function(x) x.Elements("ColumnUid").Value = "AVAIL" And 
x.Elements("Value").Value = "Y").
Select(Function(x) x.<ItemCode>.Value).ToList

        MessageBox.Show(result.Count)

However this never seems to return anything, I have Tried many variations of the Where and Select parts of the Query without Success. I am new to LINQ and can guess the query is constructed incorrectly, possibly not accessing the correct Element in the right way.

Any Help would be greatly appreciated.


I came up with this:

Dim isAvail = xDoc.<DataTable>.<Rows>.<Row>.<Cells>.
              Where(Function(x) x.<Cell>.<ColumnUid>.Value = "AVAIL" AndAlso
                                x.<Cell>.<Value>.Value = "Y")


Dim availItemCodes = isAvail.<Cell>.
                     Where(Function(y) y.<ColumnUid>.Value = "ItemCode").<Value>.
                     Select(Function(v) v.Value)

isAvail is the list (well, IEnumerable) of <Cells> which have the desired <Cell> in them.

You can see how breaking it down into smaller statements makes it easier to work with.


An all in one approach, a more complex query admittedly, First the XML

    Dim someXML As XElement
    'to load from file
    ' someXML=XElement.Load("path here")
    'OR parse string
    ' someXML = XElement.Parse("string here")
    'OR for testing use a literal

    someXML = <DataTable Uid="DT_RetRes">
                  <Rows>
                      <Row>
                          <Cells>
                              <Cell>
                                  <ColumnUid>AVAIL</ColumnUid>
                                  <Value>N</Value>
                              </Cell>
                              <Cell>
                                  <ColumnUid>ItemCode</ColumnUid>
                                  <Value>PRODUCTID123#</Value>
                              </Cell>
                              <Cell>
                                  <ColumnUid>Dscription</ColumnUid>
                                  <Value>Basic Product 1 with hash</Value>
                              </Cell>
                              <Cell>
                                  <ColumnUid>U_JOW_CMNT</ColumnUid>
                                  <Value></Value>
                              </Cell>
                          </Cells>
                      </Row>
                      <Row>
                          <Cells>
                              <Cell>
                                  <ColumnUid>AVAIL</ColumnUid>
                                  <Value>Y</Value>
                              </Cell>
                              <Cell>
                                  <ColumnUid>ItemCode</ColumnUid>
                                  <Value>PRODUCTID234</Value>
                              </Cell>
                              <Cell>
                                  <ColumnUid>Dscription</ColumnUid>
                                  <Value>Basic Product 2 no hash</Value>
                              </Cell>
                              <Cell>
                                  <ColumnUid>U_JOW_CMNT</ColumnUid>
                                  <Value></Value>
                              </Cell>
                          </Cells>
                      </Row>
                  </Rows>
              </DataTable>

Then the code

    Dim ie As IEnumerable(Of String)
    ie = From el In someXML.<Rows>.<Row>.<Cells>.<Cell>
            Where el.<ColumnUid>.Value = "AVAIL" AndAlso el.<Value>.Value = "Y"
             From item In el.Parent.<Cell>
                Where item.<ColumnUid>.Value = "ItemCode"
                Select item.<Value>.Value