1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

preg_match and XML nodes

Discussion in 'PHP' started by stupidfly, Aug 10, 2007.

  1. #1
    I'm reading an xml file. The xml file has several different nodes with the same name. When I use preg_match to get a specific node, it returns everything between the start of the first node of the desired name and the end of the last node of the desired name.
    Here is the xml code
    
    <?xml version="1.0" encoding="iso-8859-1"?>
    <users>
     <user>
       <name>James Doe</name>
       <age>23</age>
     </user>
     <user>
       <name>Sally O' Mally</name>
       <age>50</age>
     </user>
     <user>
       <name>George Bush the 2nd</name>
       <age>50</age>
     </user>
    </users>
    
    Code (markup):
    and here is my PHP code
    
    $xml = file_get_contents('users.xml');
    preg_match('/<name>([\s\S]*)<\/name>/',$xml,$userName);
    print $userName[1];
    
    Code (markup):
    What that displays is
    James Doe</name>
       <age>23</age>
     </user>
     <user>
       <name>Sally O' Mally</name>
       <age>50</age>
    
     </user>
     <user>
       <name>George Bush the 2nd
    Code (markup):
    I want it to only display the first name, James Doe.

    It is important to note that the contents of the xml document change. The structure of course is always the same. I have played around with making the parameters more specific, but then it only works when I put the correct number of spaces.
    SEMrush
     
    stupidfly, Aug 10, 2007 IP
    SEMrush
  2. sea otter

    sea otter Peon

    Messages:
    250
    Likes Received:
    23
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Use this as your preg_match() search pattern:

    
    '/\<name\>(.+)\<\/name\>/sU'
    
    Code (markup):
    Tested and works with your posted data file and 3-line code snippet.
     
    sea otter, Aug 10, 2007 IP
    stupidfly likes this.
  3. stupidfly

    stupidfly Peon

    Messages:
    129
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Thanks. It works!

    It looks like I needed to add \ before every arrow?
     
    stupidfly, Aug 10, 2007 IP
  4. sea otter

    sea otter Peon

    Messages:
    250
    Likes Received:
    23
    Best Answers:
    0
    Trophy Points:
    0
    #4
    That and the (.+) as your main pattern, but the real secret is the sU pattern modifiers, as discussed here: http://us3.php.net/manual/en/reference.pcre.pattern.modifiers.php

    Last year I wrote a bbcode parser, very similar in essence to what you're doing. Spent about a day mucking around with pattern modifiers and whatnot to get it to work. I just saw your post, so I dredged up my old code and then modified it to handle xml angle brackets instead of bbcode square brackets.

    As an aside, the code works fine if you have spaces, tabs and line breaks around, between and within the <name> tags, so you might want to strip leading/trailing spaces off of $userName[1] after the preg() call.

    If you're worried about spaces and tabs and linebreaks appearing within the name itself, you could also collapse those into a single space character after the preg() call as well.
     
    sea otter, Aug 10, 2007 IP