none
Check if XML string contains multiple specific nodes

    Question

  • Is there an easier way to check a string of XML for multiple nodes/attributes rather than creating a bunch of IF statements?

    The string of XML may contain nodes I don't care about but I want to make sure certain nodes and attributes are existing.

    Once again, thank you!

    Wednesday, July 11, 2012 7:08 PM

Answers

  • Use XPath and use a SelectNodes and see what it returns. 

    http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.selectnodes%28v=vs.90%29.aspx


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/


    • Edited by JohnGrove Wednesday, July 11, 2012 7:12 PM
    • Marked as answer by snarestudios Wednesday, July 11, 2012 8:24 PM
    Wednesday, July 11, 2012 7:11 PM
  • As I said, use the SelectNodes method and then you can get a count from that.

    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    • Marked as answer by snarestudios Wednesday, July 11, 2012 7:54 PM
    Wednesday, July 11, 2012 7:41 PM

All replies

  • Use XPath and use a SelectNodes and see what it returns. 

    http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.selectnodes%28v=vs.90%29.aspx


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/


    • Edited by JohnGrove Wednesday, July 11, 2012 7:12 PM
    • Marked as answer by snarestudios Wednesday, July 11, 2012 8:24 PM
    Wednesday, July 11, 2012 7:11 PM
  • What do you mean exactly, if elements (or attriblutes) exist only, of if there are values for each of them there too?

     Check here: http://stackoverflow.com/questions/1039628/c-sharp-linq-to-xml-check-if-element-exists?rq=1


    Mitja


    • Edited by Mitja Bonca Wednesday, July 11, 2012 7:25 PM
    Wednesday, July 11, 2012 7:24 PM
  • I am just looking to see if the node itself or attribute itself exists.  I do not care about the values/innertext as of this point.  Right now I am pulling all the nodes/attributes that I want to use via XPath and assigning them to string variables.  The only thing is, if a request is sent in and that request does not contain one of the nodes I am looking for, it throws "Object reference not set" (which I expect).  I am wanting to throw my own "graceful" error in this case and not just throw the exception.
    Wednesday, July 11, 2012 7:36 PM
  • As I said, use the SelectNodes method and then you can get a count from that.

    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    • Marked as answer by snarestudios Wednesday, July 11, 2012 7:54 PM
    Wednesday, July 11, 2012 7:41 PM
  • I'm retarded...  Thank you.  That worked perfect John.
    Wednesday, July 11, 2012 7:54 PM
  • One other question though...  Can I capture which node name is missing?  I get I can compare the return count against my known count but is there a way to say node name "BAR" is missing...  and not just return a "not all required nodes are present"?
    Wednesday, July 11, 2012 8:09 PM
  • check the nodes for null. If it is null it contains nothing at all. It doesn't exist..

    John Grove, Senior Software Engineer http://www.digitizedschematic.com/


    • Edited by JohnGrove Wednesday, July 11, 2012 8:18 PM
    Wednesday, July 11, 2012 8:18 PM
  • So would it be something like?:

    XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(StrOfXmlElements); StringBuilder sb = new StringBuilder(); XmlNodeList nodeList = xmlDoc.SelectNodes("//reqNode1[@id] | //reqNode2 | //reqNode3"); foreach (XmlNode reqNode in nodeList) { if (reqNode == null) sb.Append(reqNode.Name + " "); } return sb.ToString();

    Wednesday, July 11, 2012 8:41 PM
  • I don't know what your data looks like but your XPath looks suspect.

    //reqNode1[@id = '1']

    What exactly are you trying to get at?


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    Wednesday, July 11, 2012 8:43 PM
  • The XML stream may be something like:

    <?xml version="1.0" encoding="UTF-8"?>
    <test version="1.1">
      <testValidation type="validation" id="1">
        <reqNode1 id="Ref01.a41">
          <name>
            <personName>
              <firstName>John</firstName>
              <lastName>Doe</lastName>
            </personName>
          </name>
          <reqNode2 type="id">2</reqNode2>
          <role>
            <reqNode3>filer</reqNode3>
          </role>
        </reqNode1>
      </testValidation>
    </test>
      

    and I really only care that the three required nodes are there (reqNode1, reqNode2, reqNode3).  If the node is not in there, then I want to return my own error stating "reqNode3 does not exist".

    Wednesday, July 11, 2012 8:51 PM
  • So you want to examine all nodes of reqNode1 (which may be many) for the following nodes (reqNode2, reNode3)?

    So you can have XML that looks like so?

    <?xml version="1.0" encoding="UTF-8"?>
    <test version="1.1">
      <testValidation type="validation" id="1">
        <reqNode1 id="Ref01.a41">
          <name>
            <personName>
              <firstName>John</firstName>
              <lastName>Doe</lastName>
            </personName>
          </name>
          <reqNode2 type="id">2</reqNode2>
          <role>
            <reqNode3>filer</reqNode3>
          </role>
        </reqNode1>
        <reqNode1 id="Ref02.a45">
          <name>
            <personName>
              <firstName>John</firstName>
              <lastName>Doe</lastName>
            </personName>
          </name>     
          <role>
            <reqNode3>filer</reqNode3>
          </role>
        </reqNode1>
        <reqNode1 id="Ref51.a51">
          <name>
            <personName>
              <firstName>John</firstName>
              <lastName>Doe</lastName>
            </personName>
          </name>
          <reqNode2 type="id">2</reqNode2>
          <role/>     
        </reqNode1>
      </testValidation>
    </test>


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/


    • Edited by JohnGrove Wednesday, July 11, 2012 9:01 PM
    Wednesday, July 11, 2012 9:00 PM
  • If that is the case, than maybe something like so?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                XmlDocument xml = new XmlDocument();
                xml.Load("example.xml");
                XmlNodeList nodeList = xml.DocumentElement.SelectNodes("//reqNode1");
                foreach (XmlNode node in nodeList)
                {
                    XmlNodeList reqNodes = node.ChildNodes;
                    Console.WriteLine("");
                    Console.WriteLine("For reqNode1[id={0}]", node.Attributes["id"].Value);
                    Console.WriteLine("---------------------------");
                    foreach (XmlNode reqNode in reqNodes)
                    {
                        if (reqNode.Name == "name" || reqNode.Name == "role")
                        {
                            XmlNodeList childNodes = reqNode.ChildNodes;
                            foreach (XmlNode childNode in childNodes)                        
                                Console.WriteLine(childNode.Name);                                              
                        }
                        Console.WriteLine(reqNode.Name);                    
                    }
                }
                Console.ReadLine();
            }
        }
    }
    


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    Wednesday, July 11, 2012 9:16 PM
  • The nodes may not necessarily be children.  That was just a quick example.  Technically, I don't care where the nodes are in the XML structure, just that they are there.  I can loop through the nodes once I validate they are there.
    Wednesday, July 11, 2012 9:28 PM