pkg://jd_2.0.0~beta080418.orig.tar.gz:513216/
jd-2.0.0-beta080418/
src/
xml/document.cpp
downloads
// License GPL2
//#define _DEBUG
#include "jddebug.h"
#include "document.h"
#include "jdlib/miscutil.h"
enum
{
SIZE_OF_RAWDATA = 2 * 1024 * 1024
};
using namespace XML;
// 文字列を元にノードツリーを作る場合( htmlはHTMLモード。デフォルト = false )
Document::Document( const std::string& str, const bool html )
: Dom( NODE_TYPE_DOCUMENT, "#document", html )
{
init( str );
}
// Gtk::TreeStore を元にノードツリーを作る場合
Document::Document( Glib::RefPtr< Gtk::TreeStore > treestore, const std::string& root_name )
: Dom( NODE_TYPE_DOCUMENT, "#document" )
{
init( treestore, root_name );
}
// 何も無い状態からノードツリーを作る場合
Document::Document()
: Dom( NODE_TYPE_DOCUMENT, "#document" )
{}
//
// このクラスは代入可能
//
Document& Document::operator=( const Document& document )
{
if( this == &document ) return *this;
copy_childNodes( document );
return *this;
}
//
// 初期化
//
void Document::init( const std::string& str )
{
clear();
if( ! str.empty() ) parse( remove_comments( str ) );
}
void Document::init( Glib::RefPtr< Gtk::TreeStore > treestore, const std::string& root_name )
{
clear();
// XMLとして必要なのでルート要素を作成
Dom* root = appendChild( NODE_TYPE_ELEMENT, root_name );
// ルート以下に追加
root->parse( treestore->children() );
}
//
// 予めコメントやXML宣言などを取り除いておく( 順番に注意 )
//
std::string Document::remove_comments( const std::string& str )
{
if( str.size() > SIZE_OF_RAWDATA ) return std::string();
std::string out_str = str;
out_str = MISC::remove_str( out_str, "<!--", "-->" ); // <!-- <example /> -->
out_str = MISC::remove_str( out_str, "<?", "?>" ); // <?xml version="1.0" encoding="UTF-8"?>
out_str = MISC::remove_str( out_str, "<![", "]>" ); // <![CDATA[ <a href="exmple">*</a> ]]>
out_str = MISC::remove_str( out_str, "<!", ">" ); // <!DOCTYPE example "*">
return out_str;
}
//
// Gtk::TreeStore をセット
//
// list_path_expand = 後で Gtk::TreeView::expand_row() をするためのリスト
//
void Document::set_treestore( Glib::RefPtr< Gtk::TreeStore >& treestore, const std::string& root_name, std::list< Gtk::TreePath >& list_path_expand )
{
treestore->clear();
if( childNodes().size() )
{
// ルートの子要素以下が対象
Dom* root = get_root_element( root_name );
// ルート要素の有無で処理を分ける( 旧様式=無, 新様式=有 )
if( root ) root->append_treestore( treestore, list_path_expand );
else append_treestore( treestore, list_path_expand );
}
}
//
// ルート要素を取得
//
Dom* Document::get_root_element( const std::string& node_name )
{
Dom* node = 0;
if( ! this ) return node;
DomList children = childNodes();
std::list< Dom* >::iterator it = children.begin();
while( it != children.end() )
{
if( (*it)->nodeType() == NODE_TYPE_ELEMENT )
{
// 要素名問わず
if( node_name.empty() ) node = *it;
// 要素名限定
else if( (*it)->nodeName() == node_name ) node = *it;
break;
}
++it;
}
return node;
}