Poco::XML::SAXParser

Poco::XML::SAXParser を紹介します。

さらに、Poco::XML::ContentHandler, Poco::XML::LexicalHandler, Poco::XML::Attributes, Poco::XML::Locator も紹介します。

SAXParserTest.cpp

Poco::XML::SAXParser をインスタンス化し、setFeature() で幾つか設定。
setContentHandler()ContentHandler を登録。
setProperty()LexicalHandler を登録。
parseString() で、const な文字列を読み込み。
・MyHandler::characters() 内で、先頭の ‘\n’ と ‘\t’ を読み飛ばし。

#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"
#include "PrepareConsoleLogger.h"
 
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";
 
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;
};
 
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());
	}
}
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("SAXParserTest ", "start", "end");
 
	TestSAXParser(msg, kXMLString);
 
	return 0;
}

Results of execution

[0] SAXParserTest start
[0] --- original xml ---
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Sample HTML</title>
		<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
		<link href="css/styles.css" rel="stylesheet" type="text/css"/>
	</head>
	<body>This is a sample.</body>
</html>
 
[0] --- parsed ---
[0] - startDocument (line 1, col 0)
[0] - startDTD (line 2, col 120)
[0] - endDTD (line 2, col 120)
[0] - startPrefixMapping (line 3, col 0)
[0]     prefix=, uri=http://www.w3.org/1999/xhtml
[0] - startElement (line 3, col 0)
[0]     uri:       http://www.w3.org/1999/xhtml
[0]     localName: html
[0]     qname:     html
[0] - startElement (line 4, col 1)
[0]     uri:       http://www.w3.org/1999/xhtml
[0]     localName: head
[0]     qname:     head
[0] - startElement (line 5, col 2)
[0]     uri:       http://www.w3.org/1999/xhtml
[0]     localName: title
[0]     qname:     title
[0] - characters (line 5, col 9)
[0] Sample HTML
[0] - endElement (line 5, col 20)
[0] - startElement (line 6, col 2)
[0]     uri:       http://www.w3.org/1999/xhtml
[0]     localName: meta
[0]     qname:     meta
[0]     Attributes: 
[0]      content="text/html; charset=utf-8"
[0]      http-equiv="content-type"
[0] - endElement (line 6, col 70)
[0] - startElement (line 7, col 2)
[0]     uri:       http://www.w3.org/1999/xhtml
[0]     localName: link
[0]     qname:     link
[0]     Attributes: 
[0]      href="css/styles.css"
[0]      rel="stylesheet"
[0]      type="text/css"
[0] - endElement (line 7, col 64)
[0] - endElement (line 8, col 1)
[0] - startElement (line 9, col 1)
[0]     uri:       http://www.w3.org/1999/xhtml
[0]     localName: body
[0]     qname:     body
[0] - characters (line 9, col 7)
[0] This is a sample.
[0] - endElement (line 9, col 24)
[0] - endElement (line 10, col 0)
[0] - endPrefixMapping (line 10, col 0)
[0]     prefix=
[0] - endDocument (line 11, col 0)
[0] SAXParserTest end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年8月8日からのダウンロード数:914

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">