XMLReader.cc 3.17 KB
/*
 * XMLReader.cc
 *
 *  Created on: 7 août 2013
 *      Author: CS
 */

#include "XMLReader.hh"
#include <boost/algorithm/string.hpp>

namespace TimeTableCatalog {

XMLReader::XMLReader(const std::string& pPath) :
		AbstractReader(pPath), _tmpIntervalstartdate(0), _step(READ_STEP::NO_TAG) {

}

XMLReader::~XMLReader() {
}

// ----------------- PUBLIC --------------------------

void XMLReader::read(TimeTable& pTT) {
	/*
	 * this initialize the library and check potential ABI mismatches
	 * between the version it was compiled for and the actual shared
	 * library used.
	 */LIBXML_TEST_VERSION

	// -- parse xml file and process nodes
	parse(pTT);

	// -- cleanup function for the XML library.
	xmlCleanupParser();
}

bool XMLReader::canRead(const std::string& pPath) {
	std::string tmpPath(pPath);
	std::transform(tmpPath.begin(), tmpPath.end(), tmpPath.begin(), ::tolower);
	if(!boost::algorithm::ends_with(tmpPath, ".xml")){
		return false;
	}
	/*
	 * this initialize the library and check potential ABI mismatches
	 * between the version it was compiled for and the actual shared
	 * library used.
	 */LIBXML_TEST_VERSION

	 std::string localPath = TimeTable::download(pPath);

	// -- parse xml file and process nodes
	bool found = containsNode(localPath, getFirstNode());

	// -- cleanup function for the XML library.
	xmlCleanupParser();

	return found;
}
// ----------------- PROTECTED --------------------------

/**
 * Parses and processes XML file denoted by _path.
 */
void XMLReader::parse(TimeTable& pTT) {
	xmlTextReaderPtr reader;

	// created XML reader
	reader = xmlReaderForFile(getLocalPath().c_str(), NULL, 0);
	_step = READ_STEP::NO_TAG;
	if (reader != NULL) {
		// read xml file tag by tag
		int crtIndex = 0;
		int ret = xmlTextReaderRead(reader);
		while (ret == 1) {
			processNode(pTT, reader, crtIndex);
			ret = xmlTextReaderRead(reader);
		}
		xmlFreeTextReader(reader);
		if (ret != 0) {
			LOG4CXX_WARN(_logger, "Failed to parse " + getPath());
		}
	} else {
		LOG4CXX_WARN(_logger, "Unable to open " + getPath());
	}
}

/**
 * Parses and search for a given node in XML file denoted by _path.
 */
bool XMLReader::containsNode(const std::string& pPath, std::string pNodeName,
		int pMaxTagToRead) {
	xmlTextReaderPtr reader;

	// created XML reader
	reader = xmlReaderForFile(pPath.c_str(), NULL, 0);
	if (reader != NULL) {
		// read xml file tag by tag
		int ret = xmlTextReaderRead(reader);
		bool found = false;
		int i = 0;
		while (ret == 1 && !found && i < pMaxTagToRead) {
			found = containsNode(reader, pNodeName);
			ret = xmlTextReaderRead(reader);
			++i;
		}
		xmlFreeTextReader(reader);
		if (!found && i < pMaxTagToRead && ret != 0) {
			LOG4CXX_WARN(_logger, "Failed to parse " + pPath);
		}
		return found;
	} else {
		LOG4CXX_WARN(_logger, "Unable to open " + pPath);
	}
	return false;
}

bool XMLReader::containsNode(xmlTextReaderPtr reader,
		std::string& pNodeName) {
	const xmlChar *name;

	// -- read tag
	name = xmlTextReaderConstName(reader);
	if (name == NULL)
		name = BAD_CAST "--";

	// get tag name to easily handle it
	std::string tagName = reinterpret_cast<const char*>(name);

	if (tagName == pNodeName) {
		return true;
	}
	return false;
}

} /* namespace TimeTableCatalog */