0

I was unable to find an answer to my question after browsing some promising titles so I figured I would try my luck!

I'm attempting to extract information from XML files generated from a back-end we use at work. The information is not formatted like a normal XML document, so it's been a little difficult to extract what I need. I'm hoping that I can eventually put this information in a table, but I'll be happy if I can at least extract the values.

An example string is as follows:

<Event Name="Last Reef" VenueName="Theater" EventDate="2014-03-21 15:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259"/>

And I'm trying to get:

Event Name:
Venue Name:
Event Date:
Direct Link:

I'm assuming I need to use substr, but I've never dealt with a string like this.

If you take a moment to look at this, I would greatly appreciate it!

w5m
  • 2,286
  • 3
  • 34
  • 46
notchris
  • 180
  • 10
  • 3
    The formatting is correct for an XML document (assuming that this is just a fragment of a document). You need to be looking at how to find the values of attributes (Name, VenueName, EventDate, DirectLink are attributes of the Event element). Look at http://www.php.net/manual/en/simplexmlelement.attributes.php for hints. – GarethL Mar 20 '14 at 14:01
  • What gave you the impression that it was poorly formatted? Was it because it made use of attributes rather than nested elements? – w5m Mar 20 '14 at 14:07
  • @w5m - To tell you the truth, I'm not very familiar with XML documents, when I read some examples online, they didn't seem to use attributes as heavily. After reading the links provided, I now understand how attributes work in XML documents and that it IS correct formatting. Thank you. – notchris Mar 20 '14 at 14:10
  • No problem - I was just curious. – w5m Mar 20 '14 at 14:18

4 Answers4

3

simplexml_load_string() makes working with XML easy for basic tasks like this:

<?php
$event= simplexml_load_string('<Event Name="Last Reef" VenueName="Theater" EventDate="2014-03-21 15:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259"/>');
?>

Event Name: <?= $event['Name']; ?><br>
Venue Name: <?= $event['VenueName']; ?><br>
Event Date: <?= $event['EventDate']; ?><br>
Direct Link: <?= $event['DirectLink']; ?>

See it in action

John Conde
  • 217,595
  • 99
  • 455
  • 496
  • Thank you as well! This works great. In the XML document, there are about 20 instances of that string, it currently shows the first one, how would I make it display for each string? – notchris Mar 20 '14 at 14:07
  • 1
    It would be worth you looking at XPath if you need more power in your data manipulations. – w5m Mar 20 '14 at 14:09
  • Thank you @w5m, I'm look at the documentation for it now. – notchris Mar 20 '14 at 14:15
  • For example: print_r($event->xpath("//Event")); does a global search for all "Event" elements and returns the corresponding array. See: http://www.tuxradar.com/practicalphp/12/3/3 – w5m Mar 20 '14 at 14:16
  • @w5m - This page is very helpful! Thanks again for your help. – notchris Mar 20 '14 at 14:24
1

Or try a regex:

$str = '<Event Name="Last Reef" VenueName="Theater" EventDate="2014-03-21 15:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259"/>';

preg_match('/Name="([^"]*)".+VenueName="([^"]*)".+EventDate="([^"]*)".+DirectLink="([^"]*)"/',$str,$output);

echo '<pre>';

print_r($output);

Output:

Array
(
    [0] => Name="Last Reef" VenueName="Theater" EventDate="2014-03-21 15:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259"
    [1] => Last Reef
    [2] => Theater
    [3] => 2014-03-21 15:00:00
    [4] => https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259
)
KennyDope
  • 429
  • 1
  • 4
  • 13
1

Below is a simple example I've come up with which uses XPath to return all matching Event elements and outputs the data as an HTML table (view output here) and uses the attribute names as column headings. I added in an extra Event element to demonstrate iterating over multiple elements (and wrapped the Event elements within an Events element as valid XML documents must have a single root element).

<?php

function FormatData($data, $linkText = 'Link') {
  if (substr($data, 0, 4) === 'http') {
    if ($linkText === '') $linkText = $data;
    return sprintf('<a href="%s">%s</a>', $data, $linkText);        
  } else {
    return $data;
  }
}    

$xmlData = simplexml_load_string('<Events><Event Name="Last Reef" VenueName="Theater" EventDate="2014-03-21 15:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259"/><Event Name="Hidden Universe" VenueName="Theater" EventDate="2014-03-22 13:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45695"/></Events>');

// do a global search to retrieve all "Event" elements
$events = $xmlData->xpath('//Event');

if (count($events) > 0) {

  // get attribute names of first "Event" element
  foreach($events[0]->attributes() as $attribute) {
    $attributeNames[] = $attribute->getName(); 
  }
  // output as table column headings
  echo '<table border="1"><tr><th>' . implode('</th><th>', $attributeNames) . '</th></tr>';

  // iterate through each "Event" element and access each attribute value
  foreach($events as $event) {
    echo '<tr>';
    foreach($attributeNames as $attributeName) {
      echo '<td>' . FormatData($event[$attributeName]) . '</td>';
    }
    echo '</tr>';   
  } 
  echo '</table>';

} else {
  echo 'No matching elements found';
}

?>
w5m
  • 2,286
  • 3
  • 34
  • 46
  • Hey this is great - thank you very much @w5m! I really appreciate your help and I've learned a good amount about XML / Xpath from asking my original question! – notchris Mar 21 '14 at 13:11
  • So I guess now my only concern now is that the last column of links do not auto-link. I was just looking at this [link](https://github.com/gregjacobs/Autolinker.js), and I was wondering how to target (I assume the best way is jQuery) the content in those columns. – notchris Mar 21 '14 at 13:47
  • Actually, I think I've solved this issue, here is an example: [link](http://dev.ctsciencecenter.org/xmlpeo/) – notchris Mar 21 '14 at 14:00
  • Unfortunately, the 2nd link you provided was blocked so I can't see how you implemented it. The 1st link (Autolinker.js) looks very useful and comprehensive. If your needs were very basic you could create a simple function that assumes any attribute value beginning with "http" should be formatted as a hyperlink - see my edited post. – w5m Mar 21 '14 at 14:22
  • Are you using a phone? I have mobile devices blocked for that site. Your implementation works great - I wish I was more familiar with selecting specific content with PHP, I'm going to try your method because it doesn't require jQuery. – notchris Mar 21 '14 at 14:34
  • 1
    No, I'm using Chrome on a laptop. A few useful functions for string manipulation that are worth knowing are: substr (return a portion of a string), strpos (find position of text within a string) and str_replace (replace occurrences of text within a string). For a full list see: http://uk1.php.net/manual/en/ref.strings.php and if you want real power, try Regular Expressions! – w5m Mar 21 '14 at 15:15
0

I think, SimpleXml can do this. Just add Some like this:

 $xml_string = '<Event Name="Last Reef" VenueName="Theater" EventDate="2014-03-21 15:00:00" DirectLink="https://tickets.ctsciencecenter.org/Public/loader.asp?target=hall.asp?event=45259"/>';  
 $xml        = simplexml_load_string('<?xml version="1.0"?> '.$xml_string);
 $attributes =$xml->attributes();
 echo 'Event Name:'.$attributes['Name'];
 echo 'Venue Name:'.$attributes['VenueName'];
 echo 'Event Date:'.$attributes['EventDate'];
 echo 'Direct Link:'.$attributes['DirectLink'];
Igor Sheko
  • 56
  • 6