LINQ - Nested element with certain attributes - Asked By Pete Smith on 21-Jun-12 07:46 AM


Hi,

Im really struggling to get my head round this.

I want to get back an IEnumerable<XElement> of products from an xml file.

Below is a sample of the xml structure.

I need to get a list of products that have the productEnriched custom attribute set as true.

Some products wont have any custom attribute section at all

my head has strated to hurt just thinking about it!


<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.mynamespace.com" catalog-id="MvgCatalog">
    <product>
      <custom-attributes>
        <custom-attribute attribute-id="productEnriched">true</custom-attribute>
      </custom-attributes>
    </product>
</category>


thanks for any help
Raman S V replied to Pete Smith on 21-Jun-12 07:46 AM
Hi,
can you please give some details of the code you are using. Do you want to create nested elements in LINQ?

Regards,
Raman S V
Pete Smith replied to Raman S V on 21-Jun-12 08:00 AM


Im using c#

The intention is to open the xml file, query a list of relavent products that meet the criteria above, then i will foreach through the list and do something with the records (in the xml above i removed all the other elements to make it a bit clearer)


So if the product record has a <custom-attributes> section and has the following custom attribute with the value tru <custom-attribute attribute-id="productEnriched">true</custom-attribute> then include it in the list, otherwise dont.

am i making sense?
TSN ... replied to Pete Smith on 21-Jun-12 09:47 AM

you can easily work out in this fashion.

 

<catalog xmlns="http://www.mynamespace.com" catalog-id="MvgCatalog">
<product>
<custom-attributes>
<custom-attribute attribute-id="productEnriched">true</custom-attribute>
</custom-attributes>
</product>
< /category>

below is the Query which selects all the custom attributes with value true

XDocument loaded = XDocument.Load(@"C:\Products.xml");

var result = from c in loaded.Descendants("custom-attributes")

      where c.Attribute("custom-attribute ") == true

      select (string)c.Element("custom-attribute ")

Pete Smith replied to TSN ... on 21-Jun-12 09:55 AM

Thats not what i am after

It needs to be <custom-attribute> with the attribute attribute-id="productEnriched" and value of true

custom-attribute is an element not an attribute

it also needs to return a list of product records
Pete Smith replied to Pete Smith on 22-Jun-12 05:02 AM

To clear things up i have added a few more items to the example xml

I need to get a list of products
only products that have a custom-attribute element with the attribute productEnriched and value of true
some products in the xml wont have any custom-attribute or custom-attributes elements
some products will have it but with a value of false
i just need a list of products where it exists and has a value of true
is it possible? or am i best just getting a complete list of products and then checking each one in the foreach loop?


<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.mynamespace.com" catalog-id="MvgCatalog">
    <product>
    <upc>000000000000</upc> 
    <productTitle>My product name</productTitle>
    <custom-attributes>
      <custom-attribute attribute-id="productEnriched">true</custom-attribute>
      <custom-attribute attribute-id="somethingElse">4</custom-attribute>
      <custom-attribute attribute-id="anotherThing">otherdata</custom-attribute>
    </custom-attributes>
    </product>
</category>
Pete Smith replied to Pete Smith on 22-Jun-12 07:05 AM

I have a response now (can't claim credit as was from another message board but thaught i would include in case people have simular)

var xml = XElement.Load(@"your file.xml");
XNamespace ns = "http://www.mynamespace.com";
var products = xml.Elements(ns + "product");
var filtered = products.Where(
    product
=>
        product
.Element(ns + "custom-attributes") != null &&
        product
.Element(ns + "custom-attributes").Elements(ns + "custom-attribute")
       
.Any(
            ca
=>
                ca
.Value == "true" &&
                ca
.Attribute("attribute-id") != null &&
                ca
.Attribute("attribute-id").Value == "productEnriched"));
Pete Smith replied to Pete Smith on 22-Jun-12 07:05 AM

I have a response now (can't claim credit as was from another message board but thaught i would include in case people have simular)

var xml = XElement.Load(@"your file.xml");
XNamespace ns = "http://www.mynamespace.com";
var products = xml.Elements(ns + "product");
var filtered = products.Where(
    product
=>
        product
.Element(ns + "custom-attributes") != null &&
        product
.Element(ns + "custom-attributes").Elements(ns + "custom-attribute")
       
.Any(
            ca
=>
                ca
.Value == "true" &&
                ca
.Attribute("attribute-id") != null &&
                ca
.Attribute("attribute-id").Value == "productEnriched"));