Create a gist now

Instantly share code, notes, and snippets.

@rinevo /Makefile
Last active Aug 29, 2015

What would you like to do?
libxmlでXMLファイルから特定要素のXML文を取得
#Makefile
xmlGetTagString: xmlGetTagString.cpp
g++ -o xmlGetTagString xmlGetTagString.cpp `xml2-config --cflags --libs`
clean:
rm -f xmlGetTagString.o
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <libxml/xmlreader.h>
using namespace std;
int main(int argc, char *argv[])
{
xmlChar* val;
char* file;
vector<string> tags;
string target;
string str;
int type;
int depth;
int tagNo;
int ret;
// コマンドライン引数から読込ファイルを取得
if (argc != 3) {
printf("error (argc != 3)\n");
return 1;
}
file = argv[1];
target = argv[2];
// 目的のElementまでのタグ名を分解
std::istringstream ss(target);
while (std::getline(ss, str, '/')) {
tags.push_back(str);
}
// XMLファイル読込
xmlTextReaderPtr reader = xmlNewTextReaderFilename(file);
if (!reader) {
printf("xmlNewTextReaderFilename error\n");
return 1;
}
// XMLの先頭Node取得
ret = xmlTextReaderRead(reader);
tagNo = 0;
target = tags[tagNo];
while (ret == 1) {
// Nodeタイプ取得
type = xmlTextReaderNodeType(reader);
// Elementを見つけるまで順に検索
if (type != XML_READER_TYPE_ELEMENT) {
ret = xmlTextReaderRead(reader);
continue;
}
// 階層チェック
depth = xmlTextReaderDepth(reader);
if (tagNo != depth) {
printf("depth error!\n");
break;
}
// タグ名を取得
val = xmlTextReaderName(reader);
str = (char*)val;
xmlFree(val);
cout << "current name: " << str << ", tagNo=" << tagNo << ", depth=" << depth << endl;
// target名と一致するか?
if (str == target) {
// 最後のtagまで一致したか?
tagNo++;
if (tagNo == tags.size()) {
// 目的のElement
xmlTextReaderExpand(reader);
val = xmlTextReaderReadInnerXml(reader);
printf("xmlTextReaderReadInnerXml=%s\n", val);
xmlFree(val);
break;
} else {
target = tags[tagNo];
}
// 子階層を含む次のNode
ret = xmlTextReaderRead(reader);
} else {
// 同じ階層の次のNode
ret = xmlTextReaderNext(reader);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment