Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Select an XML attribute and another attribute using xpath (without Linq)

1.00/5 (2 votes)
6 Nov 2011CPOL 12.1K  
Select an XML attribute and another attribute using xpath.
How do we select all blingy wheels with a 5 bolt pattern using a XPath Statement?

(*Without linq*)

XML
<Car>
       <Wheel brand="HRE" boltPattern="5" Bling="True"></Wheel>
       <Wheel brand="stockHonda" boltPattern="4" Bling="False"></Wheel>
       <Wheel name="MOMO" boltPattern="4" Bling="True"></Wheel>
       <Wheel name="SomeCrapRim" boltPattern="5" Bling="false"></Wheel>
   </Car>


Answer:
C#
Select( xmlString, new string[] { "Cars/Wheel[@boltPattern='5']", "node()/Wheel[@Bling='True']"});


Note: This is not optimized code, it is example code. There is no need to load up the document over and over.

C#
/// <summary>
    /// To combine multiple select statements to parse XML data
    /// This allows you to do statements such as:
    ///     get all elements where attributeA ="X" and attributeB ="Y"
    ///
    ///     Select( new string()[] { "node()/[@attributeA='X']",
    ///                              "node()/[@attributeB='Y']"}
    /// These statements are impossible in one single xPathSyntax
    /// but using this we can combine them.
    ///
    /// notes:
    ///  -Be aware that after a select parent element names
    ///   will be truncated and only one "root" element will remain.
    ///   Therefore you must use "node()" for all the select statements
    ///   except for the first one.
    ///   -To do an "or" operation you can use "node()/elementX | node()/elementY"
    ///   which would effectively return both elements.
    ///   -select examples:
    ///    http://msdn.microsoft.com/en-us/library/ms256086.aspx
    ///   -testing tool
    ///   http://www.xmlme.com/XpathTool.aspx
    /// </summary>
    /// <param name="xmlSource"></param>
    /// <param name="xPaths"></param>
    /// <returns></returns>
    public static string Select(string xmlSource, string[] xPaths)
    {
        string xmlresult = xmlSource;
        for (int i = 0; i < xPaths.Length; i++)
        {
            xmlresult = Select(xmlresult, xPaths[i]);
        }
        return xmlresult;
    }

    /// <summary>
    /// Returns all subsequent nodes of an xPath select statement in a single XML string.
    /// The returned string wraps the elements in a "root" element.
    ///
    /// This is useful for parsing XML elements.
    /// notes: - This is not optimized. Use for UI only atm.
    ///
    /// </summary>
    /// <param name="xmlSource"></param>
    /// <param name="xPath"></param>
    /// <returns></returns>
    public static string Select(string xmlSource, string xPath)
    {
        if (xmlSource.Length == 0)
        {
            return String.Empty;
        }
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlSource);
        XPathNavigator nav = doc.CreateNavigator();
        XPathNodeIterator iter1 = nav.Select(xPath);
        if (iter1.Count == 0)
        {
            return String.Empty;
        }
        StringBuilder xml = new StringBuilder();
        xml.Append("<root>");
        while (iter1.MoveNext())
        {
            xml.Append(iter1.Current.OuterXml);
            xml.Append("\r\n");
        }
        xml.Append("</root>");
        return xml.ToString();
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)