diff --git a/src/framework/Libxml2Adapter.cpp b/src/framework/Libxml2Adapter.cpp
index d30a890a93cc58ce2e8be73cfbb05a0369aa4d19..ac5416a17ad66323c94cd44e53d21c682f834a75 100644
--- a/src/framework/Libxml2Adapter.cpp
+++ b/src/framework/Libxml2Adapter.cpp
@@ -20,15 +20,71 @@
 
 #include "Libxml2Adapter.h"
 
+#include <iostream>
+#include <sstream>
+
+#include <libxml/xpath.h>
+
 Libxml2Adapter::Libxml2Adapter()
 {
+	m_xmlDocument = NULL;
 }
 
 Libxml2Adapter::~Libxml2Adapter()
 {
 }
 
-string Libxml2Adapter::getAttributeBySingleElementXPath(const string xml, const string xpath)
+void Libxml2Adapter::setXmlDocument(const string xml, const string url)
 {
-	//TODO
+	xmlDocPtr doc = xmlReadMemory(xml.c_str(), xml.size(), url.c_str(), NULL, 0);
+	if(doc) {
+		m_xmlDocument = doc;
+	}
+	else {
+		cerr << "Document couldn't be parsed!" << endl;
+	}
 }
+
+string Libxml2Adapter::getSingleNodeContentByXPath(const string xpath)
+{
+	// no document available!
+	if(!m_xmlDocument) return("");
+
+	// prepare xpath search
+	stringstream buffer;
+    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(m_xmlDocument);
+    xmlChar* xpathExpr = xmlCharStrdup(xpath.c_str());
+
+    // run xpath query
+    xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
+    xmlNodeSetPtr nodes = xpathObj->nodesetval;
+
+    // how many nodes did we find?
+    int size = (nodes) ? nodes->nodeNr : 0;
+
+    if(size == 0) {
+    	cerr << "No node found using XPath expression: " << xpath << endl;
+    	return("");
+    }
+    else if(size < 1) {
+    	cerr << "More than node found using XPath expression: " << xpath << endl;
+    	return("");
+    }
+
+    // convert xml contents
+    buffer << xmlNodeListGetString(m_xmlDocument, nodes->nodeTab[0]->xmlChildrenNode, 1);
+
+    // clean up
+    xmlXPathFreeObject(xpathObj);
+    xmlXPathFreeContext(xpathCtx);
+
+    return(buffer.str());
+}
+
+string Libxml2Adapter::getSingleNodeContentByXPath(const string xml, const string url, const string xpath)
+{
+	setXmlDocument(xml, url);
+	return(getSingleNodeContentByXPath(xpath));
+}
+
+
diff --git a/src/framework/Libxml2Adapter.h b/src/framework/Libxml2Adapter.h
index a07f673cb2f8fe17039108ff3e9c635a29eca049..92ca84b026b3cc94198d423e511953f6d63817b7 100644
--- a/src/framework/Libxml2Adapter.h
+++ b/src/framework/Libxml2Adapter.h
@@ -25,6 +25,8 @@
 
 #include "XMLProcessorInterface.h"
 
+#include <libxml/parser.h>
+
 using namespace std;
 
 /**
@@ -33,14 +35,14 @@ using namespace std;
  */
 
 /**
- * \brief This class implements XMLProcessorInterface providing an adapter to libxml2 
- * 
+ * \brief This class implements XMLProcessorInterface providing an adapter to libxml2
+ *
  * For the time being libxml2 is considered to be the only interesting XML processing
  * library because of its rich feature set that comprises DOM, SAX, XPath, XSLT as well
  * as validation based on DTD and XML Schema.
- * 
+ *
  * \see XMLProcessorInterface
- * 
+ *
  * \author Oliver Bock\n
  * Max-Planck-Institute for Gravitational Physics\n
  * Hannover, Germany
@@ -53,21 +55,48 @@ public:
 
 	/// Destructor
 	virtual ~Libxml2Adapter();
-	
+
+	/**
+	 * \brief Sets the XML document to be processed
+	 *
+	 * \param xml The XML document to be used for processing
+	 * \param url The base URL of the document
+	 */
+	void setXmlDocument(const string xml, const string url);
+
 	/**
-	 * \brief Retrieves a single element's attribute value
-	 * 
+	 * \brief Retrieves a single node's (element or attribute) content
+	 *
 	 * This method takes a XPath expression that properly defines how to search
-	 * for a specific attribute of a single element. If the XPath search results
-	 * in more than one element or if the attribute can't be found the return
-	 * value is NULL.
-	 * 
+	 * for a specific node (element or attribute). If the XPath search results
+	 * in more than one instance or if the node (or its content) can't be found
+	 * the return value is NULL.
+	 *
+	 * \param xpath The XPath expression to be used for seaching
+	 *
+	 * \return The node's content or NULL in case of an error
+	 */
+	string getSingleNodeContentByXPath(const string xpath);
+
+	/**
+	 * \brief Retrieves a single node's (element or attribute) content
+	 *
+	 * This method takes a XPath expression that properly defines how to search
+	 * for a specific node (element or attribute). If the XPath search results
+	 * in more than one instance or if the node (or its content) can't be found
+	 * the return value is NULL.
+	 *
 	 * \param xml The XML document to be used for processing
+	 * \param url The base URL of the document
 	 * \param xpath The XPath expression to be used for seaching
-	 * 
-	 * \return The attribute value or NULL in case of an error
+	 *
+	 * \return The node's content or NULL in case of an error
 	 */
-	string getAttributeBySingleElementXPath(const string xml, const string xpath);
+	string getSingleNodeContentByXPath(const string xml, const string url, const string xpath);
+
+private:
+	/// The current XML document instance
+	xmlDocPtr m_xmlDocument;
 };
 
 /**
diff --git a/src/framework/Makefile b/src/framework/Makefile
index 57a06f1d2f947d1d454691cc161add44725d8da8..8a8ace7110f39510e81e225ff88be1ee8f1224f9 100644
--- a/src/framework/Makefile
+++ b/src/framework/Makefile
@@ -28,6 +28,7 @@ CXX?=g++
 # variables
 CPPFLAGS = $(shell $(FRAMEWORK_INSTALL)/bin/sdl-config --cflags)
 CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/freetype-config --cflags)
+CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(FRAMEWORK_INSTALL)/include/BOINC -I/usr/include
 
 DEPS = Makefile
diff --git a/src/framework/XMLProcessorInterface.h b/src/framework/XMLProcessorInterface.h
index d799eac94b3bebbdbf56387dc44cf3c1f28d4d2c..8daa7079cf83d46e36bb7efea72b9c0b3ddae0bf 100644
--- a/src/framework/XMLProcessorInterface.h
+++ b/src/framework/XMLProcessorInterface.h
@@ -33,12 +33,12 @@ using namespace std;
 /**
  * \brief This interface declares all mandatory public methods to be provied by any
  * given XML Processor.
- * 
+ *
  * All classes implementing this interface have to provide at least the set of methods
- * declared here. 
- * 
+ * declared here.
+ *
  * \see Libxml2Adapter
- * 
+ *
  * \author Oliver Bock\n
  * Max-Planck-Institute for Gravitational Physics\n
  * Hannover, Germany
@@ -46,24 +46,47 @@ using namespace std;
 class XMLProcessorInterface
 {
 public:
-	
+
 	/// Empty Destructor
 	virtual ~XMLProcessorInterface() {};
-	
+
+	/**
+	 * \brief Sets the XML document to be processed
+	 *
+	 * \param xml The XML document to be used for processing
+	 * \param url The base URL of the document
+	 */
+	virtual void setXmlDocument(const string xml, const string url) = 0;
+
+	/**
+	 * \brief Retrieves a single node's (element or attribute) content
+	 *
+	 * This method takes a XPath expression that properly defines how to search
+	 * for a specific node (element or attribute). If the XPath search results
+	 * in more than one instance or if the node (or its content) can't be found
+	 * the return value is NULL.
+	 *
+	 * \param xpath The XPath expression to be used for seaching
+	 *
+	 * \return The node's content or NULL in case of an error
+	 */
+	virtual string getSingleNodeContentByXPath(const string xpath) = 0;
+
 	/**
-	 * \brief Retrieves a single element's attribute value
-	 * 
+	 * \brief Retrieves a single node's (element or attribute) content
+	 *
 	 * This method takes a XPath expression that properly defines how to search
-	 * for a specific attribute of a single element. If the XPath search results
-	 * in more than one element or if the attribute can't be found the return
-	 * value is NULL.
-	 * 
+	 * for a specific node (element or attribute). If the XPath search results
+	 * in more than one instance or if the node (or its content) can't be found
+	 * the return value is NULL.
+	 *
 	 * \param xml The XML document to be used for processing
+	 * \param url The base URL of the document
 	 * \param xpath The XPath expression to be used for seaching
-	 * 
-	 * \return The attribute value or NULL in case of an error
+	 *
+	 * \return The node's content or NULL in case of an error
 	 */
-	virtual string getAttributeBySingleElementXPath(const string xml, const string xpath) = 0;
+	virtual string getSingleNodeContentByXPath(const string xml, const string url, const string xpath) = 0;
 };
 
 /**
diff --git a/src/starsphere/EinsteinRadioAdapter.cpp b/src/starsphere/EinsteinRadioAdapter.cpp
index 21e86b094d387e5186db1453d194f591c3f9e450..9877367da4d05893c2a539cc735c7ce4fb4a8268 100644
--- a/src/starsphere/EinsteinRadioAdapter.cpp
+++ b/src/starsphere/EinsteinRadioAdapter.cpp
@@ -19,6 +19,9 @@
  ***************************************************************************/
 
 #include "EinsteinRadioAdapter.h"
+#include "Libxml2Adapter.h"
+
+#include <cstdlib>
 
 const string EinsteinRadioAdapter::SharedMemoryIdentifier = "EinsteinRadio";
 
@@ -26,6 +29,7 @@ EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) :
 	m_WUTemplatePowerSpectrum(POWERSPECTRUM_BINS, 0)
 {
 	this->boincClient = boincClient;
+	m_xmlIFace = new Libxml2Adapter();
 
 	m_WUSkyPosRightAscension = 0.0;
 	m_WUSkyPosDeclination = 0.0;
@@ -35,6 +39,7 @@ EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) :
 
 EinsteinRadioAdapter::~EinsteinRadioAdapter()
 {
+	if(m_xmlIFace) delete m_xmlIFace;
 }
 
 void EinsteinRadioAdapter::refresh()
@@ -45,71 +50,67 @@ void EinsteinRadioAdapter::refresh()
 
 void EinsteinRadioAdapter::parseApplicationInformation()
 {
-	char spectrumArray[POWERSPECTRUM_BIN_BYTES + 1] = {0};
+	string spectrumString;
 
 	// get updated application information
 	string info = boincClient->applicationInformation();
 
 	// do we have any data?
 	if(info.length() > 0) {
+		string temp;
 
 		// parse data into members
-		// TODO: this is soon going to be replaced by true XML parsing!
-		if(9 != sscanf(info.c_str(),
-				"<graphics_info>\n"
-				"  <skypos_rac>%lf</skypos_rac>\n"
-				"  <skypos_dec>%lf</skypos_dec>\n"
-				"  <dispersion>%lf</dispersion>\n"
-				"  <orb_radius>%lf</orb_radius>\n"
-				"  <orb_period>%lf</orb_period\n"
-				"  <orb_phase>%lf</orb_phase>\n"
-				"  <power_spectrum>%80c</power_spectrum>\n"
-				"  <fraction_done>%lf</fraction_done>\n"
-				"  <cpu_time>%lf</cpu_time>\n",
-				&m_WUSkyPosRightAscension,
-				&m_WUSkyPosDeclination,
-				&m_WUDispersionMeasure,
-				&m_WUTemplateOrbitalRadius,
-				&m_WUTemplateOrbitalPeriod,
-				&m_WUTemplateOrbitalPhase,
-				spectrumArray,
-				&m_WUFractionDone,
-				&m_WUCPUTime))
-		{
-			cerr << "Incompatible shared memory data encountered!" << endl;
-		}
-		else {
-			// convert radians to degrees
-			m_WUSkyPosRightAscension *= 180/PI;
-			m_WUSkyPosDeclination *= 180/PI;
-
-			// deserialize power spectrum data
-			string spectrumString(spectrumArray);
-			if(spectrumString.length() == POWERSPECTRUM_BIN_BYTES) {
-				int spectrumBinValue;
-				// prepare hex to int conversion stream
-				istringstream spectrumBinStream;
-				spectrumBinStream.exceptions(ios_base::badbit | ios_base::failbit);
-				// iterate over all bins
-				for(int i = 0, j = 0; i < POWERSPECTRUM_BIN_BYTES; i += 2, ++j) {
-					try {
-						spectrumBinStream.str(spectrumString.substr(i, 2));
-						// convert hex bin value to integer
-						spectrumBinStream >> hex >> spectrumBinValue;
-						// store bin power value
-						m_WUTemplatePowerSpectrum.at(j) = (unsigned char) spectrumBinValue;
-						spectrumBinStream.clear();
-					}
-					catch(ios_base::failure) {
-						cerr << "Error processing power spectrum shared memory data!" << endl;
-						break;
-					}
+		m_xmlIFace->setXmlDocument(info, "http://einstein.phys.uwm.edu");
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/skypos_rac");
+		m_WUSkyPosRightAscension = strtod(temp.c_str(), NULL);
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/skypos_dec");
+		m_WUSkyPosDeclination = strtod(temp.c_str(), NULL);
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/dispersion");
+		m_WUDispersionMeasure = strtod(temp.c_str(), NULL);
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_radius");
+		m_WUTemplateOrbitalRadius = strtod(temp.c_str(), NULL);
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_period");
+		m_WUTemplateOrbitalPeriod = strtod(temp.c_str(), NULL);
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_phase");
+		m_WUTemplateOrbitalPhase = strtod(temp.c_str(), NULL);
+		spectrumString = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/power_spectrum");
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/fraction_done");
+		m_WUFractionDone = strtod(temp.c_str(), NULL);
+		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/cpu_time");
+		m_WUCPUTime = strtod(temp.c_str(), NULL);
+
+		// TODO: make sure parsing worked flawlessly (only spectrum is checked below!)
+
+		// convert radians to degrees
+		m_WUSkyPosRightAscension *= 180/PI;
+		m_WUSkyPosDeclination *= 180/PI;
+
+		// deserialize power spectrum data
+		if(spectrumString.length() == POWERSPECTRUM_BIN_BYTES) {
+			int spectrumBinValue;
+			// prepare hex to int conversion stream
+			istringstream spectrumBinStream;
+			spectrumBinStream.exceptions(ios_base::badbit | ios_base::failbit);
+			// iterate over all bins
+			for(int i = 0, j = 0; i < POWERSPECTRUM_BIN_BYTES; i += 2, ++j) {
+				try {
+					spectrumBinStream.str(spectrumString.substr(i, 2));
+					// convert hex bin value to integer
+					spectrumBinStream >> hex >> spectrumBinValue;
+					// store bin power value
+					m_WUTemplatePowerSpectrum.at(j) = (unsigned char) spectrumBinValue;
+					spectrumBinStream.clear();
+				}
+				catch(ios_base::failure) {
+					cerr << "Error processing power spectrum shared memory data!" << endl;
+					break;
 				}
 			}
-			else {
-				cerr << "Invalid power spectrum shared memory data encountered!" << endl;
-			}
 		}
+		else {
+			cerr << "Invalid power spectrum shared memory data encountered!" << endl;
+		}
+
 	}
 }
 
diff --git a/src/starsphere/EinsteinRadioAdapter.h b/src/starsphere/EinsteinRadioAdapter.h
index 22469d370ab6255bb264643933e779d2c12d5b39..3970126380a7bd7181da0cf6c080cef4a1a7e830 100644
--- a/src/starsphere/EinsteinRadioAdapter.h
+++ b/src/starsphere/EinsteinRadioAdapter.h
@@ -26,6 +26,7 @@
 #include <iomanip>
 
 #include "BOINCClientAdapter.h"
+#include "XMLProcessorInterface.h"
 
 using namespace std;
 
@@ -152,6 +153,9 @@ private:
 	/// Pointer to the (parent) BOINC client adapter
 	BOINCClientAdapter *boincClient;
 
+	/// Pointer to the XML processor
+	XMLProcessorInterface* m_xmlIFace;
+
 	/// Right ascension of the currently searched sky position (in degrees)
 	double m_WUSkyPosRightAscension;
 
diff --git a/src/starsphere/Makefile b/src/starsphere/Makefile
index 4520abd004a1328eaac2dd9890dbba3974f94350..bf9530b21f295ecd666b3a6f43dc19d6107ab69a 100644
--- a/src/starsphere/Makefile
+++ b/src/starsphere/Makefile
@@ -28,12 +28,14 @@ CXX ?= g++
 # variables
 LIBS = -Wl,-Bstatic -lframework -loglft -L$(STARSPHERE_INSTALL)/lib
 LIBS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --libs)
+LIBS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --libs)
 LIBS += -lboinc_api -lboinc -L/usr/lib
 LIBS += -Wl,-Bdynamic $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --static-libs) -lGL -lGLU
 
 CPPFLAGS = -I$(STARSPHERE_INSTALL)/include
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --cflags)
+CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include/BOINC -I/usr/include
 
 DEPS = Makefile