root/trunk/0056_SAXParser/SAXParserTest.cpp

User picture

Author: Setsu

Revision: 348 («Previous)


File Size: 7.26 KB

(August 07, 2010 20:12 UTC) Almost 2 years ago

Unused header removed.

 
Show/hide line numbers
//
//  SAXParserTest.cpp
//
//  Created by Setsu on 8/5/2010.
//  Copyright 2010 RoundSquare Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

//----------------------------------------
//	include
//----------------------------------------
#include <Poco/Logger.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/SAX/SAXParser.h>
#include <Poco/SAX/ContentHandler.h>
#include <Poco/SAX/LexicalHandler.h>
#include <Poco/SAX/Attributes.h>
#include <Poco/SAX/Locator.h>
#include <Poco/Exception.h>
#include <Poco/Format.h>

#include <string>

#include "ScopedLogMessage.h"

//----------------------------------------
//	const
//----------------------------------------
const std::string kXMLString =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
"	<head>\n"
"		<title>Sample HTML</title>\n"
"		<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\"/>\n"
"		<link href=\"css/styles.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
"	</head>\n"
"	<body>This is a sample.</body>\n"
"</html>\n";

//----------------------------------------
//	MyHandler
//----------------------------------------
class MyHandler : public Poco::XML::ContentHandler, public Poco::XML::LexicalHandler
{
public:
	MyHandler(ScopedLogMessage& msg) :
		m_pLocator(0)
	,	m_Msg(msg)
	{
	}
	
	// ContentHandler
	void setDocumentLocator(const Poco::XML::Locator* loc)
	{
		m_pLocator = loc;
	}
	
	void startDocument()
	{
		where("startDocument");
	}
	
	void endDocument()
	{
		where("endDocument");
	}
	
	void startElement(const Poco::XML::XMLString& uri, const Poco::XML::XMLString& localName, const Poco::XML::XMLString& qname, const Poco::XML::Attributes& attributes)
	{
		where("startElement");
		m_Msg.Message(Poco::format("    uri:       %s", uri));
		m_Msg.Message(Poco::format("    localName: %s", localName));
		m_Msg.Message(Poco::format("    qname:     %s", qname));
		if(0 != attributes.getLength())
		{
			m_Msg.Message("    Attributes: ");
			for(int i=0; i<attributes.getLength(); ++i)
			{
				m_Msg.Message(Poco::format("     %s=\"%s\"", attributes.getLocalName(i), attributes.getValue(i)));
			}
		}
	}
	
	void endElement(const Poco::XML::XMLString& uri, const Poco::XML::XMLString& localName, const Poco::XML::XMLString& qname)
	{
		where("endElement");
	}
	
	void characters(const Poco::XML::XMLChar ch[], int start, int length)
	{
		int myStart = start;
		int myLength = length;
		while((0 != myLength) && (('\n' == ch[myStart]) || ('\t' == ch[myStart])))
		{
			++myStart;
			--myLength;
		}
		if(0 != myLength)
		{
			where("characters");
			m_Msg.Message(std::string(ch + myStart, myLength));
		}
	}
	
	void ignorableWhitespace(const Poco::XML::XMLChar ch[], int start, int length)
	{
		where("ignorableWhitespace");
	}
	
	void processingInstruction(const Poco::XML::XMLString& target, const Poco::XML::XMLString& data)
	{
		where("processingInstruction");
		m_Msg.Message(Poco::format("    target=%s, data=%s", target, data));
	}
	
	void startPrefixMapping(const Poco::XML::XMLString& prefix, const Poco::XML::XMLString& uri)
	{
		where("startPrefixMapping");
		m_Msg.Message(Poco::format("    prefix=%s, uri=%s", prefix, uri));
	}
	
	void endPrefixMapping(const Poco::XML::XMLString& prefix)
	{
		where("endPrefixMapping");
		m_Msg.Message(Poco::format("    prefix=%s", prefix));
	}
	
	void skippedEntity(const Poco::XML::XMLString& name)
	{
		where("skippedEntity");
		m_Msg.Message(Poco::format("    name=%s", name));
	}
	
	// LexicalHandler
	void startDTD(const Poco::XML::XMLString& name, const Poco::XML::XMLString& publicId, const Poco::XML::XMLString& systemId)
	{
		where("startDTD");
	}
	
	void endDTD()
	{
		where("endDTD");
	}
	
	void startEntity(const Poco::XML::XMLString& name)
	{
		where("startEntity");
	}
	
	void endEntity(const Poco::XML::XMLString& name)
	{
		where("endEntity");
	}
	
	void startCDATA()
	{
		where("startCDATA");
	}
	
	void endCDATA()
	{
		where("endCDATA");
	}
	
	void comment(const Poco::XML::XMLChar ch[], int start, int length)
	{
		where("comment");
	}
	
protected:
	void where(const std::string& meth)
	{
		if(m_pLocator)
		{
			m_Msg.Message(Poco::format("- %s (line %i, col %i)",
										meth,
										m_pLocator->getLineNumber(),
										m_pLocator->getColumnNumber()));
		}
		else
		{
			m_Msg.Message(Poco::format("- %s", meth));
		}
	}
	
private:
	const Poco::XML::Locator*	m_pLocator;
	ScopedLogMessage&			m_Msg;
};

//----------------------------------------
//	TestSAXParser
//----------------------------------------
void TestSAXParser(ScopedLogMessage& msg, const std::string& xml)
{
	msg.Message("--- original xml ---\n" + xml);

	MyHandler handler(msg);

	Poco::XML::SAXParser parser;
	parser.setFeature(Poco::XML::XMLReader::FEATURE_NAMESPACES, true);
	parser.setFeature(Poco::XML::XMLReader::FEATURE_NAMESPACE_PREFIXES, true);
	parser.setContentHandler(&handler);
	parser.setProperty(Poco::XML::XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<Poco::XML::LexicalHandler*>(&handler));
	
	try
	{
		msg.Message("--- parsed ---");
		parser.parseString(kXMLString);
	}
	catch(Poco::Exception& exc)
	{
		msg.Message(exc.displayText());
	}
}

//----------------------------------------
//	PrepareConsoleLogger
//----------------------------------------
void PrepareConsoleLogger(const std::string& name, int level=Poco::Message::PRIO_INFORMATION)
{
	Poco::FormattingChannel* pFCConsole = new Poco::FormattingChannel(new Poco::PatternFormatter("%t"));
	pFCConsole->setChannel(new Poco::ConsoleChannel);
	pFCConsole->open();

	Poco::Logger::create(name, pFCConsole, level);
}

//----------------------------------------
//	main
//----------------------------------------
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);

	ScopedLogMessage msg("SAXParserTest ", "start", "end");

	TestSAXParser(msg, kXMLString);

	return 0;
}