Search code examples
c#xmllinqxmlnode

Find XML-Node with certain value with C#


Given a XML with a structure like this:

<?xml version="1.0" encoding="UTF-8"?>
<BMECAT version="2005" xmlns="http://www.bmecat.org/bmecat/2005+onto" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eclass.eu/static/eClassXML/2.0/bmecat/bmecat_2005onto.xsd">
    <T_NEW_CATALOG>
        <PRODUCT mode="new">            
            <PRODUCT_FEATURES>
                <FEATURE>
                    <FTEMPLATE>
                        <FT_ID>0173-1#02-BAC137#006</FT_ID>
                        <FT_NAME>Breite</FT_NAME>
                    </FTEMPLATE>
                    <FVALUE>10</FVALUE>
                    <FUNIT>0173-1#05-AAA480#003</FUNIT>
                    <FID>375397708</FID>
                    <FPARENT_ID>-1</FPARENT_ID>
                </FEATURE>
                <FEATURE>
                    <FTEMPLATE>
                        <FT_ID>0173-1#02-BAC476#007</FT_ID>
                        <FT_NAME>Höhe</FT_NAME>
                    </FTEMPLATE>
                    <FVALUE>51.5</FVALUE>
                    <FUNIT>0173-1#05-AAA480#003</FUNIT>
                    <FID>375397709</FID>
                    <FPARENT_ID>-1</FPARENT_ID>
                </FEATURE>
                <FEATURE>
                    <FTEMPLATE>
                        <FT_ID>0173-1#02-BAA351#014</FT_ID>
                        <FT_NAME>Farbe</FT_NAME>
                    </FTEMPLATE>
                    <VALUE_IDREF>0173-1#07-AAA875#004</VALUE_IDREF>
                    <FID>375397710</FID>
                    <FPARENT_ID>-1</FPARENT_ID>
                </FEATURE>
                <FEATURE>
                    <FTEMPLATE>
                        <FT_ID>0173-1#02-BAA018#007</FT_ID>
                        <FT_NAME>Länge</FT_NAME>
                    </FTEMPLATE>
                    <FVALUE>55.5</FVALUE>
                    <FUNIT>0173-1#05-AAA480#003</FUNIT>
                    <FID>375397711</FID>
                    <FPARENT_ID>-1</FPARENT_ID>
                </FEATURE>
            </PRODUCT_FEATURES>
        </PRODUCT>
    </T_NEW_CATALOG>
</BMECAT>
    

In a first step, I want to select all FEATURE Elements with the FT_NAME "Breite". After that, I want to get the FVALUE of that FEATURE.

I tried to do that using


XElement root = XElement.Load("File.xml");
IEnumerable<XElement> elements =
    from el in root.Elements("FEATURE")
    where (string)el.Element("FT_NAME") == "Breite"
    select el;

but I don't get any results.


Solution

  • There are a couple of problems here:

    • Elements only returns direct child elements - not all descendants. Your root document doesn't contain any FEATURE elements as direct children, nor do the FEATURE elements contain FT_NAME elements as direct children. You can use Descendants instead of Elements for this
    • Your elements are all in the http://www.bmecat.org/bmecat/2005+onto namespace, but you haven't specified that anywhere.

    Here's a code sample that fixes both issues:

    XNamespace ns = "http://www.bmecat.org/bmecat/2005+onto";
    // Used XDocument instead of XElement as really that's
    // what your file contains
    var doc = XDocument.Load("Test.xml");
    
    var elements =
        from el in doc.Descendants(ns + "FEATURE")
        where (string) el.Descendants(ns + "FT_NAME").SingleOrDefault() == "Breite"
        select el;
    
    foreach (var element in elements)
    {
        Console.WriteLine(element.Element(ns + "FTEMPLATE").Element(ns + "FT_ID").Value);
    }