CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Jul 2011
    Posts
    9

    [RESOLVED] populate list/array from specific XML nodes

    I wonder if anyone can help me with this problem. What I'm trying to do is populate a string list with values based on the name from the XML file. In other words

    list list = new list
    for each row in XML file with var name "cabin",
    list.add -> cabin.value

    I then want to convert this list to and int array so I can perform numeric operations etc.
    At the moment the code I have is not populating the list atal I have tested with labels etc here it is.

    _______________________________________________________________
    //Load XML document
    XmlDocument xml = new XmlDocument();
    xml.LoadXml(Server.MapPath("~/Upload/" + FileUpload1.FileName));

    // xnList = nodes -> rows with Cabin
    XmlNodeList xnList = xml.SelectNodes("/root/row[@name=' Cabin']");

    //create a string list
    List<string> strvalues = new List<string>();

    //populate list with values @ node Cabin
    foreach (XmlNode xn in xnList)
    {
    strvalues.Add(xn["value"].InnerText); //**This line of code is trying to populate the list
    }

    //convert string array to int array for data manipulation
    int[] values = strvalues.Select(x => int.Parse(x)).ToArray();
    for (int i = 0; i < values.Length; i++)
    {
    //print array
    Debug.WriteLine(values[i]);
    }
    }
    _________________________________________________________________________


    and here is a sample of the XML file


    _________________________________________________________________________
    <root>
    <row>
    <var name="Name" value="Rusell" />
    <var name=" Surname" value=" Anthony" />
    <var name=" Country" value=" UK" />
    <var name=" Job" value="Web Designer" />
    <var name=" Cabin" value="345" />
    </row>
    <row>
    <var name="Name" value="Wolf" />
    <var name=" Surname" value=" Werner" />
    <var name=" Country" value=" Germany" />
    <var name=" Job" value="Linux IT" />
    <var name=" Cabin" value="234" />
    </row>
    </root>

    ________________________________________________________________________

    If anyone can give me a hand here Id appreciate it.

    Just to be clear,

    - the user will select a value, such as cabin from a dropdownlist.
    - I then need to put all values of Cabin into a list/array so I can use it in a method that takes an array of values as the parameter

  2. #2
    Join Date
    May 2011
    Location
    Washington State
    Posts
    220

    Re: populate list/array from specific XML nodes

    Good jump at it!

    Below, note the two things I changed...

    First your initial query of the xml to gather up the nodes with ' Cabin' as the name. I removed the initial back-slash, but more importantly, added the "var" element name to the query. The original query was asking for all <row> elements with the name=' Cabin', which you do not have any.

    The second thing changed was how you were trying to get the value, I did not test your line, but rather edited it to reflect exactly where you were trying to get the value from... if nothing else, makes it easier for someone else looking at the code to determine where in the xml they should be looking for that value.

    I didn't even touch your conversion from string to int for your array... that will be your next step as far as testing and seeing if that works out.

    Best of luck!

    Code:
    //Load XML document
    XmlDocument xml = new XmlDocument();
    xml.LoadXml(Server.MapPath("~/Upload/" + FileUpload1.FileName));
    
    // xnList = nodes -> rows with Cabin
    XmlNodeList xnList = xml.SelectNodes("root/row/var[@name=' Cabin']");
    
    //create a string list
    List<string> strvalues = new List<string>();
    
    //populate list with values @ node Cabin
    foreach (XmlNode xn in xnList)
    {
      strvalues.Add(xn.Attributes["value"].Value); //**This line of code is trying to populate the list
    }
    
    //convert string array to int array for data manipulation
    int[] values = strvalues.Select(x => int.Parse(x)).ToArray();
    for (int i = 0; i < values.Length; i++)
    {
        //print array
        Debug.WriteLine(values[i]);
    }

  3. #3
    Join Date
    Jul 2011
    Posts
    9

    Re: populate list/array from specific XML nodes

    So near yet so far Thank you so much for the fixes

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: populate list/array from specific XML nodes

    Are you in control of the xml schema? In other words, can you change how the data is layed out in xml?

  5. #5
    Join Date
    Jul 2011
    Posts
    9

    Re: populate list/array from specific XML nodes

    No the files are passed in, in this case I had to convert a .csv to XML myself, hence the spacing issue in ' Cabin'

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: populate list/array from specific XML nodes

    Quote Originally Posted by user12 View Post
    No the files are passed in, in this case I had to convert a .csv to XML myself, hence the spacing issue in ' Cabin'
    If you are converting .csv to xml, don't you have control over the format of the xml?

  7. #7
    Join Date
    Jul 2011
    Posts
    9

    Re: populate list/array from specific XML nodes

    I could probably ignore white space etc it isnt a problem I was just making the point that i cant control the incoming files. If they are not already XML, I will be converting them, to (try) make the data easier to work with

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: populate list/array from specific XML nodes

    Quote Originally Posted by user12 View Post
    I could probably ignore white space etc it isnt a problem I was just making the point that i cant control the incoming files. If they are not already XML, I will be converting them, to (try) make the data easier to work with
    I agree with adapting all the incoming data to one format. That way, your 'engine' only has to deal with one type.

    Still, the format the xml is in isn't exactly easy to do lookups on.

    I would transform the xml into a different xml schema and then load that up using Xml serialization. That way, I could store the items in a list and write an IComparer to retrieve the data as needed.

    I'd take the existing xml of...
    Code:
    <root>
      <row>
        <var name="Name" value="Rusell" />
        <var name=" Surname" value=" Anthony" />
        <var name=" Country" value=" UK" />
        <var name=" Job" value="Web Designer" />
        <var name=" Cabin" value="345" />
      </row>
      <row>
        <var name="Name" value="Wolf" />
        <var name=" Surname" value=" Werner" />
        <var name=" Country" value=" Germany" />
        <var name=" Job" value="Linux IT" />
        <var name=" Cabin" value="234" />
      </row>
    </root>
    and turn it into this...
    Code:
    <root>
      <row name="Rusell" surName="Anthony" country="UK" job="Web Designer" cabin="345" />
      <row name="Wolf" surname="Werner" country="Germany" job="Linux IT" cabin="234" />
      </row>
    </root>

  9. #9
    Join Date
    Jul 2011
    Posts
    9

    Re: populate list/array from specific XML nodes

    Thats an interesting idea. As you have probably guessed I'm new to XML altogether so I've never used XSLT files, but that format does seem a lot cleaner to work with. I'll keep it in mind thanks.

  10. #10
    Join Date
    Jul 2011
    Posts
    9

    Re: populate list/array from specific XML nodes

    Hey, just thought I'd post here rather than starting a new thread I had a shot at transforming and it went ok, format wise, here is what I got

    <root>
    <row Name="" Surname="" Country="" Job="" Cabin="" />
    <row Name="" Surname="" Country="" Job="" Cabin="" />
    <row Name="" Surname="" Country="" Job="" Cabin="" />
    <row Name="" Surname="" Country="" Job="" Cabin="" />
    </root>

    Obviously the values were not taken any idea as to why?If someone could help with the XSL syntax id be grateful. Here is the file i generated.

    You will notice for a couple of the attributes, when using value-of select I have different syntax this is just to show what I have tried.

    <xsl:template match="/">
    <root>
    <xsl:apply-templates/>

    </root>
    </xsl:template>

    <xsl:template match="row">

    <row>
    <xsl:attribute name="Name">
    <xsl:value-of select="value"/>

    </xsl:attribute>
    <xsl:attribute name="Surname">
    <xsl:value-of select="row/root/name/value"/>

    </xsl:attribute>
    <xsl:attribute name="Country">
    <xsl:value-of select="root/row/value"/>

    </xsl:attribute>
    <xsl:attribute name="Job">
    <xsl:value-of select="@value"/>

    </xsl:attribute>
    <xsl:attribute name="Cabin">
    <xsl:value-of select="value"/>

    </xsl:attribute>

    </row>

    </xsl:template>

    Also, since I will be taking in different files with different schema, is it possible create a reusable transformation file that will output in the above format by taking in all node values in the file rather than having to know what each is and hardcode them as above. This is actually pretty important for my application.
    I'm not looking for anyone to write me the code by the way if I could get a point in the right direction I'll give it my best shot

    I'll make this my last bump to the topic, just a bit overwhelmed. Thanks
    Last edited by user12; July 20th, 2011 at 12:26 PM.

  11. #11
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: populate list/array from specific XML nodes

    I can't help with the xslt but I can show you how to create a class that reads the xml after you get it transformed.

    Ask your xml/xlst question in the xml forum.
    Last edited by Arjay; July 20th, 2011 at 01:30 PM.

  12. #12
    Join Date
    May 2011
    Location
    Washington State
    Posts
    220

    Re: populate list/array from specific XML nodes

    Try this as your xsl.... (I learned today too...)

    Code:
    <?xml version="1.0"?>
    
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template match="/">
      <xml>
         <xsl:for-each select="root/row">
            <row>
               <xsl:attribute name="name">
                  <xsl:value-of select="var[@name='Name']/@value"/>
               </xsl:attribute>
               <xsl:attribute name="surname">
                  <xsl:value-of select="var[@name=' Surname']/@value"/>
               </xsl:attribute>
               <xsl:attribute name="country">
                  <xsl:value-of select="var[@name=' Country']/@value"/>
               </xsl:attribute>
               <xsl:attribute name="job">
                  <xsl:value-of select="var[@name=' Job']/@value"/>
               </xsl:attribute>
               <xsl:attribute name="cabin">
                  <xsl:value-of select="var[@name=' Cabin']/@value"/>
               </xsl:attribute>
            </row>
         </xsl:for-each>
      </xml>
    
    </xsl:template>
    </xsl:stylesheet>
    As to your second question, there is no way to handle just any XML input thrown your way without something being hard-coded up front based on some set of rules.

    What you can do however, (what I would do...), is create an XSL transform file that defines each type of XML input I can receive. Then I would create a class that is responsible for determining which XSL file to utilize to transform the file uploaded by the user. That way you can simply add a new XSL file each time you discover a new format of input you do not yet handle and you don't have to change your code. To determine which XSL to use, you either have to require the users to put 'something' in their xml that indicates to you where it's from (what format it is in), or you just have to rely on finding something unique about each input format you can key on and simply take a peek when a file comes in.

    I hope that helps!
    Last edited by fcronin; July 20th, 2011 at 02:52 PM. Reason: Second part of question.

  13. #13
    Join Date
    Jul 2011
    Posts
    9

    Re: populate list/array from specific XML nodes

    That makes a lot of sense just have multiple files that define a set of transformation rules. Seems so simple when it is typed out like that thanks for taking the time to reply you've been a great help.

  14. #14
    Join Date
    May 2011
    Location
    Washington State
    Posts
    220

    Re: populate list/array from specific XML nodes

    No problem, glad to be of help!

    You should go ahead and mark this "Resolved" if you think you're done with the thread, have a good one!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured