Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get attribute values from matching XML nodes using XPath query

This doesn't seem like it should be difficult, but I'm stuck currently. I'm trying to get the attribute values for a particular attribute from nodes that match a given XPath query string. Here's what I have so far:

    public static IEnumerable<string> GetAttributes(this XmlDocument xml,
        string xpathQuery, string attributeName)
    {
        var doc = new XPathDocument(new XmlNodeReader(xml));
        XPathNavigator nav = doc.CreateNavigator();
        XPathExpression expr = nav.Compile(xpathQuery);
        XPathNodeIterator iterator = nav.Select(expr);
        while (iterator.MoveNext())
        {
            XPathNavigator curNav = iterator.Current;
            if (curNav.HasAttributes)
            {
                XmlNode curNode = ((IHasXmlNode)curNav).GetNode();
                if (null != curNode)
                {
                    XmlAttribute attrib = curNode.Attributes[attributeName];
                    if (null != attrib)
                    {
                        yield return attrib.Value;
                    }
                }
            }
        }
    }

This currently throws an exception:

System.InvalidCastException: Unable to cast object of type 'MS.Internal.Xml.Cache.XPathDocumentNavigator' to type 'System.Xml.IHasXmlNode'.

Am I going about this wrong? Is there a simpler way to get attribute values from matching nodes?

like image 279
Sarah Vessels Avatar asked Nov 29 '10 21:11

Sarah Vessels


People also ask

Can you use XPath expression used to select the target node and its values?

XPath assertion uses XPath expression to select the target node and its values. It compares the result of an XPath expression to an expected value. XPath is an XML query language for selecting nodes from an XML. Step 1 − After clicking Add Assertion, select Assertion Category – Property Content.

What is XPath by attribute?

Definition of XPath attribute. For finding an XPath node in an XML document, use the XPath Attribute expression location path. We can use XPath to generate attribute expressions to locate nodes in an XML document.


1 Answers

If you're using .net 3.5 or later you could use linq to Xml

For a given xml document

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <storedProcedures>
    <storedProcedure name="usp_GET_HOME_PAGE_DATA">
      <resultSet name="Features"/>
      <resultSet name="Highlights"/>
    </storedProcedure>
    <storedProcedure name="usp_GET_FEATURES" />
    <storedProcedure name="usp_GET_FEATURE" />
    <storedProcedure name="usp_UPDATE_FEATURE" />
    <storedProcedure name="usp_GET_FEATURE_FOR_DISPLAY">
      <resultSet name="CurrentFeature"/>
      <resultSet name="OtherFeatures"/>
    </storedProcedure>
    <storedProcedure name="usp_GET_HIGHLIGHT_TITLES">
      <resultSet name="Highlights"/>
    </storedProcedure>
  </storedProcedures>
</root>

The following linq expression will get you the values of the "name" attributes of all storedProcedure node

XDocument xDcoument = XDocument.Load(xmlStoredProcSchemeFile);

  var storedProcedureNames = from doc in xDcoument.Descendants("storedProcedure")
                             select doc.Attribute("name").Value;

you could also use regular XPath syntax. In the code below the variable node holds the node identified by the "usp_GET_HOME_PAGE_DATA" name and then the attributes variable holds all child nodes (the attributes) of the selected node and it's children.

  XmlDocument xmlDocument = new XmlDocument();
  xmlDocument.Load(@"C:\inetpub\wwwroot\ASPNETBuilder\BusinessLayer\DataAccessCodeGenerationSchema.xml");
  var node = xmlDocument.DocumentElement.SelectSingleNode("./storedProcedures/storedProcedure[@name='usp_GET_HOME_PAGE_DATA']");
  var attributes = node.SelectNodes("./resultSet/@name");
like image 157
Shiv Kumar Avatar answered Oct 15 '22 16:10

Shiv Kumar