user1343318
user1343318

Reputation: 2141

Querying an XML File using LINQ

I have an XML file that I want to query with LINQ. I want for every record, create a new row. Here is what I have tried up till yet and have failed.

<?xml version="1.0" encoding="utf-8"?>
<categories xmlns="urn:schemas-pi-meta:categories" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:schemas-pi-meta:categories Xsd/meta.xml.config.xsd">
<category name="history">
    <data>
      <value name="customer">2</value>
      <value name="truck">1</value>
    </data>
    <category name="record">
      <data>
        <value name="time">1/3/2013 2:22:41 PM</value>
        <value name="quantity">3</value>
        <value name="unit">barrels</value>
        <value name="cancelled">false</value>
        <value name="errored">false</value>
      </data>
    </category>
  </category>

The file is longer so I have cut it down but it repeats itself.

This is what I have tried to do:

 XElement root = XElement.Load("D:\\Linq XM\\history.xml.config");

 IEnumerable<XElement> address = from el in root.Elements("categories")
    where (string)el.Attribute("category") == "record"
    select el;

I have tried to change Elements value thinking that I am perhaps missing something but somehow the query isn't returning my data.

Upvotes: 1

Views: 540

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499780

There are four problems as far as I can see.

The first problem is that you're looking for categories elements under the root element - when the categories element is the root element. I suspect you really want to be looking for category elements rather than categories elements.

The second problem is that you're trying to find an attribute named category. It looks to me like you should be checking for an attribute named name within elements called category.

The third problem is that the category with a name attribute of record isn't actually a direct child element of categories at all - it's a descendant, but not a direct child - so you should use Descendants instead of Elements.

The fourth problem is that you're not specifying a namespace. This part of the file:

<categories xmlns="urn:schemas-pi-meta:categories"  ...

specifies that the default namespace for this element and descendants is the URI "urn:schemas-pi-meta:categories". So you need to specify that when you say what you're looking for.

Putting these all together, you'd get:

XNamespace ns = "urn:schemas-pi-meta:categories";
var query = from el in root.Descendants(ns + "category")
            where (string) el.Attribute("name") == "record"
            select el;

Or without a query expression (as it's more hassle than it's worth here):

XNamespace ns = "urn:schemas-pi-meta:categories";
var query = root.Descendants(ns + "category")
                .Where(el => (string) el.Attribute("name") == "record");

Upvotes: 8

Related Questions