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

    [RESOLVED] Returning a Value

    I'm trying to write a piece of code right now using .NET 4 that takes the value of an XML node that contains someone's full name. We'll use "John Doe" as an example. I am then writing it into a new XML file with nodes "firstname" and "lastname". Therefore, I need to pull only part of the original XML node innertext at a given time. My current code is this:

    Code:
    XmlNode Contacts = Address.SelectSingleNode("Contacts");                         XmlNode Contact = Contacts.SelectSingleNode("Contact");                         XmlNode Name = Contact.SelectSingleNode("Name");                         String nameString = Name.Value.ToString();                         String firstName;                         for (int i = 0; i < nameString.IndexOf(" "); i++)                         {                                                      }                         XmlElement firstname = shipmentXMLDoc.CreateElement("first-name");                         firstname.InnerText = firstName;                         customer.AppendChild(firstname);
    Basically I want to somehow iterate through the indexof until it hits the space between the first name and last name and then I want it to take it and set it equal to the firstName string. How can I finish my for statement to accomplish this? Thanks.

  2. #2
    Join Date
    Mar 2011
    Posts
    10

    Re: Returning a Value

    The code didn't work right with the code tags around it so here it is again:

    XmlNode Contacts = Address.SelectSingleNode("Contacts");
    XmlNode Contact = Contacts.SelectSingleNode("Contact");
    XmlNode Name = Contact.SelectSingleNode("Name");
    String nameString = Name.Value.ToString();
    String firstName;
    for (int i = 0; i < nameString.IndexOf(" "); i++)
    {

    }
    XmlElement firstname = shipmentXMLDoc.CreateElement("first-name");
    firstname.InnerText = firstName;
    customer.AppendChild(firstname);

  3. #3
    Join Date
    Oct 2005
    Location
    Seattle, WA U.S.A.
    Posts
    353

    Re: Returning a Value

    Perhaps it would be possible to eliminate the FOR loop and just use a regular expression to take what you want ...

    Code:
                Regex firstNameBasis = new Regex("^\\s*(?<firstName>\\w+)");
                string nameString = "    Sid Dhartha      ";
                string firstName = firstNameBasis.Match(nameString ).Groups["firstName"].Value;
    Last edited by ThermoSight; March 21st, 2011 at 12:42 PM.

  4. #4
    Join Date
    Mar 2011
    Posts
    10

    Re: Returning a Value

    I'm not sure I understand how that regular expression would work. The first and last names will change based on the xml file so it's dynamic.

  5. #5
    Join Date
    Oct 2005
    Location
    Seattle, WA U.S.A.
    Posts
    353

    Re: Returning a Value

    Hmmm, I see ...

    you're saying that the first and last names may change position within "nameString" ?

    So in one case I might be looking at names like "Steve Jensen" and then in another case I'd be seeing names in reverse order such as "Jensen, Steve" ?

    Ahhh, in that case, forgive me, Sir. When I looked at your code you seemed to just be iterating through the string looking for a space.

    My immediate thought was to forget the iterating and let Microsoft do the heavy lifting ... let the Regex engine iterate through the namestring and capture the first token it saw, assuming that would be the first name ... but certainly not in a situation where the name is in reverse order.

    Indeed, I might have suggested an alternative .... forget the FOR loop and just do a string.Split on a space (on a trim()'ed string, of course) .... but even then you wouldn't know which of the two-element array returned would be the first name without first analyzing them.

    (And, hopefully, it would be only a two-element array ... it might be more if there are two or more spaces inbetween the first and last name).




    Ya know, it's entirely possible that my block of code is responsible for the confusion.
    Although I am clearly SETTING nameString to a value (as you do in your code), it was not my intent to suggest that you would set it to a literal. That's just to set nameString to something so that you can try the three line block of code on your machine.

    On the contrary, you would continue to set nameString as you normally do. The important part of that code block is the regular expression definition, and its use in the Regex match statement. I believe it will capture the first token it sees. Whether that's a first name or a surname is irrelevant - it doesn't know about names, it knows only tokens.

    Try the block of code on your machine ... I think it'll work for ya.

    Sorry 'bout that ... sorry for wasting your time.

    Old Fool
    Last edited by ThermoSight; March 21st, 2011 at 01:04 PM.

  6. #6
    Join Date
    Mar 2011
    Posts
    10

    Re: Returning a Value

    No, you are right that the first and last name won't change position. I guess I don't really understand regex since I haven't used it before. My idea was to search for the index number of the space between the first and last name and then print the characters that come before the space as the first name. I'll go research regex a bit. Thanks.

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

    Re: Returning a Value

    Can you include a sample of the xml? There are several clean approaches that you can use depending on the layout of the xml.

  8. #8
    Join Date
    Oct 2005
    Location
    Seattle, WA U.S.A.
    Posts
    353

    Re: Returning a Value

    In the case where the names do NOT change order, then we're good.

    That Regex definition is a "capture". It essentially asks the engine to skip over any leading spaces it sees, then begin 'capturing' all word-elements it sees (letters regardless of case, digits, etc) until it finds a character that is not a match (not a word-element, like a space), then place what it's captured into a group known as "firstName".

    Now that I think of it, you could change the definition to replace the "\\w" with "[a-zA-Z]" to restrict the capture to letters only (no one has digits in their name).

    Regex firstNameBasis = new Regex("^\\s*(?<firstName>[a-zA-Z]+)");

  9. #9
    Join Date
    Mar 2011
    Posts
    10

    Re: Returning a Value

    Nm, figured it out. Thanks for the help, it worked awesome.
    Last edited by BerryKix; March 21st, 2011 at 01:48 PM.

  10. #10
    Join Date
    Mar 2011
    Posts
    10

    Re: Returning a Value

    Here's a relevant portion of the XML file in case you have a cleaner way of doing it, thanks:

    - <Contacts>
    - <Contact type="" oid="123469837931">
    <Name>JOHN DOE</Name>

    - <ContactMethods>
    <ContactMethod sequenceNum="1" type="Phone">(999) 999-9999</ContactMethod>

    <ContactMethod sequenceNum="2" type="Email">[email protected]</ContactMethod>

    </ContactMethods>


    </Contact>


    </Contacts>

  11. #11
    Join Date
    Mar 2011
    Posts
    10

    Re: Returning a Value

    Also, would you guys mind giving me a link to where I can find a good explanation and info on the syntax of this part. I'm going to try and do the last name now on my own after I understand this better.

    ("^\\s*(?<firstName>\\w+)

    EDIT: Figured it out. thanks again for the help.
    Last edited by BerryKix; March 21st, 2011 at 02:42 PM.

  12. #12
    Join Date
    Oct 2005
    Location
    Seattle, WA U.S.A.
    Posts
    353

    Re: [RESOLVED] Returning a Value

    Regex("^\\s*(?<firstName>[a-zA-Z]+)");

    There are two components to this Regex string: the match and the capture


    The string above asks the Regex engine to find a match for a series of characters that
    1) begins at the beginning of the string ( that's what the caret (^) means)
    2) includes zero or more space-type characters (the * is a quantifier indicating zero or more)
    3) and within the match, capture (collect) and place in group "firstName", all letters,
    regardless of case (the '+' is a quantifier indicating ONE or more)

    Now, we could do without the "^\\s*", but I generally leave it in place. Why ? Because that way I can have my cake and eat it, too. That is, with the "^\\s*" in place, I get the capture which is EXCLUSIVELY the designated token, AND I also have the Match.Value which is the captured token in situ which is sometimes significant.

    Regular expressions are viewed by many as a black art, but they're also great fun and immensely powerful in working one's way thru text. The Help section of Visual Studio contains more information on regular expressions and there are tons o' websites that do the same. And I'm sure many books devoted entirely to regular expressions have been written.

    Regular expressions are the programmer's answer to the New York Times Sunday crossword puzzle.

    Best wishes.

    OldFool.
    Last edited by ThermoSight; March 21st, 2011 at 07:23 PM.

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