LoginSignup
6
6

More than 5 years have passed since last update.

XML をパースする

Posted at

HTMLからtagを抽出する の XML/C++版。
Apache Xerces-C 3.1.1 SAXParser を使って、XMLをパースする。

#include <iostream>
#include <string>
#include <locale>
#include <vector>
#include <memory>

#define XERCES_STATIC_LIBRARY 

#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/sax/AttributeList.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>

class ParseHandler : public xercesc::HandlerBase {
public:
  /*
   * 以下の 仮想関数 がcallbackされるので好きに使うがいい。
   * このサンプルでは 
   *   <img> の src  アトリビュート と
   *   <a>   の href アトリビュート
   * を抽出する。
   */
  virtual void characters(const XMLCh* const chars, const XMLSize_t length) {}
  virtual void endDocument() {}
  virtual void endElement(const XMLCh* const name) {}
  virtual void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length) {}
  virtual void processingInstruction(const XMLCh* const target, const XMLCh* const data) {}
  virtual void resetDocument() {}
  virtual void startDocument() {}
  virtual void startElement(const XMLCh* const name, xercesc::AttributeList& attributes);

  std::vector<std::wstring> urls;
};

void ParseHandler::startElement(const XMLCh* const name, xercesc::AttributeList& attr) {
  std::wstring element(name);
  if ( element == L"a" ) {
    std::wstring value(attr.getValue("href"));
    if ( !value.empty() ) urls.push_back(value);
  } else
  if ( element == L"img" ) {
    std::wstring value(attr.getValue("src"));
    if ( !value.empty() ) urls.push_back(value);
  }
}

using namespace xercesc;
using namespace std;

int main() {
    wstring xhtml =
       L"<?xml version='1.0' ?>" 
       L"<html><body>"
       L"  <a href=\"http://qiita.com/episteme\">επιστημη</a>"
       L"  <img src=\"https://pbs.twimg.com/profile_images/54608127/epi_normal.jpg\"/>"
       L"</body></html>";

    XMLPlatformUtils::Initialize();
    {
        auto parser = make_unique<SAXParser>();
        auto handler = make_unique<ParseHandler>();
        MemBufInputSource source(reinterpret_cast<const XMLByte*>(xhtml.data()), xhtml.size()*sizeof(wchar_t), "xhtml-parse", false);
        parser->setDocumentHandler(handler.get());
        parser->parse(source);    

        // 結果を出力
        wcout.imbue(locale("japanese"));
        for ( const wstring& url : handler->urls ) {
            wcout << url << endl;
        }
    }
    XMLPlatformUtils::Terminate();
}
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6