/* vi: set tabstop=4 paste nocindent noautoindent: */
#ifndef __JBXL_TINY_XML_H_
#define __JBXL_TINY_XML_H_
/**
Tiny XML txml.h v1.0
サブセット版 整形式XML 簡易パーサ ライブラリヘッダ
全てのパターンのパース可能性を保障するものではありません
複雑な XMLは(恐らく)パースできません.
以外の ..... ?> と は処理しない(読み込みは行う)
エンティティは処理しない.
--------------------
tXML: (tXML は tList, tTree と同じもの)
1.タグデータ tXML:
int ldat.id タグの種別.XML_ANCHOR_TAG, XML_TAG_NAME, XML_TAG_CONTENT, ..........
int ldat.lv タグ値である子ノードの個数
int ldat.sz 未使用
Buffer ldat.key タグ名またはタグ値
Buffer ldat.val の未処理データと のコメント情報を格納
void* ldat.ptr 未使用
tXML* ldat.lst 属性リストへのポインタ.ldat.lst->ldat.keyに属性名,ldat.lst->ldat.valに属性値("'付き)を格納
tXML* next 子タグ(長女)へのポインタ
tXML* prev 親タグへのポインタ
tXML* altp その他へのポインタ(汎用)
tXML* back 子タグ(末っ子)へのポインタ
tXML* esis 前の姉妹(姉)タグへのポインタ
tXML* ysis 次の姉妹(妹)タグへのポインタ
int depth 深さ
int num 子ノードの数
int ctrl 制御用
int state ノードの状態 XML_PARSED, XM_TAG_OPEND, XML_TAG_ENDED, XML_PARSE_ERROR, ....
2.パースしたXML情報を格納するツリー構造
ABCEFG
の場合,次のようにパースされる.表示は ldat.key.buf (id)
NULL (XML_ANCHOR_TAG) -> xml (XML_DOC_TAG)
-> A (XML_TAG_NAME) -> B (XML_TAG_NAME) -> C (XML_TAG_NAME) -> ABC (XML_TAG_CONTENT)
-> D (XML_TAG_NAME)
-> EFG (XML_TAG_CONTENT)
-> E (XML_TAG_NAME)
-> @COMMENT_TAG (XML_COMMENT_TAG) // ただしコメントの処理は暫定的
3.タグ(ノード)種別 (ldat.id)
XML_ANCHOR_TAG アンカータグ
XML_TAG_NAME タグネーム
XML_TAG_CONTENT タグの内容(コンテント)
XML_DOC_TAG xml... ?> タグ
XML_COMMENT_TAG コメントタグ
XML_DATA_TAG タグ
XML_PROCESS_TAG XML_DOC_TAG 以外の ... ?>タグ
4.状態 (state)
XML_DEFAULT_SATE ノードは,正常にパースされたかどうかの判定はまだ行われていない.
XML_PARSED アンカータグにのみ設定される.このXMLツリーは正常にパースされたことを示す.
XML_TAG_STARTED このノードはオープン状態にある.
XML_TAG_ENDED このノードは正常にクローズした.
XML_TAG_EMPTY このノードは空要素タグである < />, , , ?> の型
XML_MULTI_ROOT アンカータグにのみ設定される.このXMLツリーは2つ以上の独立したツリーを持つ
XML_PARSE_ERROR 解釈エラー
XML_SEQUENCE_ERROR アンカーを越えてツリーを作ろうとした.
XML_MEMORY_ERROR メモリの確保エラー
*/
#include "tlist.h"
// タグ種別 (ldat.id)
#define XML_ANCHOR_TAG 0
#define XML_TAG_NAME 1
#define XML_TAG_CONTENT 2
#define XML_DOC_TAG 3
#define XML_COMMENT_TAG 4
#define XML_DATA_TAG 5
#define XML_PROCESS_TAG 6
// タグ(ノード)の状態.エラーは 0以下にする.(state)
#define XML_DEFAULT_STATE 0
#define XML_PARSED 1
#define XML_TAG_STARTED 2
#define XML_TAG_ENDED 3
#define XML_TAG_EMPTY 4
#define XML_MULTI_ROOT 9
#define XML_PARSE_ERROR -1
#define XML_SEQUENCE_ERROR -2
#define XML_MEMORY_ERROR -9
// XML Format
#define XML_ONELINE_FORMAT 0
#define XML_CRLF_FORMAT 1
#define XML_INDENT_FORMAT 2
// 代用タグ名 (ldat.key.buf) 暫定的
#define XML_COMMENT_TAG_KEY "@COMMENT_TAG"
#define XML_DATA_TAG_KEY "@DATA_TAG"
typedef struct _tList tXML;
/////////////////////////////////////////////////////////////////////////////////////////////
//
// XML Functions
//
// Paser
tXML* xml_parse(char* pp);
tXML* xml_parse_file(char* pp);
tXML* xml_parse_seq(tXML* xml, char* pp);
tXML* xml_partial_parse(tXML* xml, char* pp, int skip);
int xml_parse_content(char* pp, char** content);
tList* xml_parse_attr(char* pp);
int xml_parse_start_tag(char* pp, char** tag_name, char** tag_attr, int* tag_end);
int xml_parse_end_tag(char* pp, char** tag_name);
int xml_parse_processing_tag(char* pp, char** tag_name, char** tag_attr);
int xml_parse_comment_tag(char* pp, char** comment);
int xml_parse_data_tag(char* pp, char** data);
void close_xml(tXML* pp);
int isnot_xml_name(unsigned char* pp);
// Operation
tXML* add_xml_tag(tXML* xml, char* name);
tXML* add_xml_content(tXML* xml, char* value);
tXML* get_xml_tag(tXML* pp, tXML* pt);
int set_xml_tag(tXML* pp, tXML* pt, char* val);
int set_xml_end_tag(tXML* pp, tXML* pt);
tXML* get_xml_content(tXML* pp, tXML* pt);
int set_xml_content(tXML* pp, tXML* pt, char* val);
tList* get_xml_attr(tXML* pp, tXML* pt);
int set_xml_attr(tXML* pp, tXML* pt, tList* at);
char* get_first_tag_name(tXML* xml);
int replace_xml_content(tXML*pp, tXML* pt, char* src, char* dst);
tXML* find_match_xml_end_tag(tXML* pp, tXML* pt);
#define find_xml_top(p) find_tList_top(p)
#define find_xml_end(p) find_tTree_end(p)
//
tXML* get_xml_tag_bystr(tXML* pp, char* str);
int set_xml_tag_bystr(tXML* pp, char* str, char* val);
int set_xml_end_tag_bystr(tXML* pp, char* str);
tXML* get_xml_content_bystr(tXML* pp, char* str);
int set_xml_content_bystr(tXML* pp, char* str, char* val);
tList* get_xml_attr_bystr(tXML* pp, char* str);
int set_xml_attr_bystr(tXML* pp, char* pt, tList* at);
int replace_xml_content_bystr(tXML*pp, char* str, char* src, char* dst);
// Operation for multi tags
tList* get_xml_tag_list(tXML* pp, tXML* pt);
tList* get_xml_content_list(tXML* pp, tXML* pt);
int set_xml_content_list(tXML* pp, tXML* pt, char* content);
tList* get_xml_tag_list_bystr(tXML* pp, char* str);
tList* get_xml_content_list_bystr(tXML* pp, char* str);
int set_xml_content_list_bystr(tXML* pp, char* str, char* content);
//
tXML* dup_merge_xml(tXML* pp, tXML* tp);
void print_xml(FILE* fp, tXML* pp, int mode);
void print_xml_tree(FILE* fp, tXML* pp, char* space);
void print_sister_xml_tree(FILE* fp, tXML* pp, char* space);
void print_sister_xml_tree_rcsv(FILE* fp, tXML* pp, char* space);
tXML* del_xml(tXML** pp);
void del_all_xml(tXML** pp);
tXML* del_sister_xml(tXML** pp);
tXML* del_sisters_children_xml(tXML** pp);
// 逆パース
Buffer xml_inverse_parse(tXML* pp, int mode);
void xml_to_Buffer(tXML* pp, Buffer* buf, int mode, int indent);
void xml_opentag_to_Buffer (tXML* pp, Buffer* buf, int mode, int indent);
void xml_closetag_to_Buffer(tXML* pp, Buffer* buf, int mode, int indent);
void xml_attr_to_Buffer(tList* pp, Buffer* buf);
///////////////////////////////////////////////////////////////////////////////////////////
// Search XML Tag (tTree用の関数とほぼ同じ)
int find_match_xml(tXML* pp, tXML* pt);
tXML* find_match_xml_endlist(tXML* pp, tXML* pt);
tList* find_match_xml_endlist_rcsv(tXML* pp, tXML* pt, tXML* te);
int check_match_xml(tXML* tp, tXML* tr);
tXML* cmp_sisters_xml(tXML* tp, tXML* tr);
/////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple Tag Funxtions.
//
int get_tag_integer (tXML* tp, char* name, int no);
Buffer get_tag_content (tXML* tp, char* name, int no);
int return_exist_tag(tXML* tp, char* name, int no, Buffer* value);
int replace_all_tag_integer (tXML* tp, char* name, int src, int dst);
int replace_all_tag_contents(tXML* tp, char* name, char* src, char* dst);
int replace_all_tag_contents_rcsv(tXML* tp, char* name, char* src, char* dst);
int replace_all_tag_byid(tXML* tp, char* src, char* dst, int id);
int replace_all_tag_byid_rcsv(tXML* tp, char* src, char* dst, int id);
/**/
#endif