Sedna XML Database(纯XML数据库)

引用baidu对xml数据库定义: 纯XML数据库,其特点是以自然的方式处理XML数据,以XML文档作为基本的逻辑存储单位,针对XML的数据存储和查询特点专门设计适用的数据模型和处理方法。

WikiXMLDB是将XML格式化的Wikipedia 内容存储在Sedna数据库中,并提供了 XQuery访问接口。

WikiXMLDB provides a way of querying Wikipedia with XQuery. We have parsed Wikipedia content into well-structured XML representation, loaded it into Sedna XML database and implemented an XQuery Web interface.

Here is where WikiXMLDB comes to the rescue. We have parsed the entire English Wikipedia content into XML representation (its total size is about 44GB), loaded it into Sedna and provided a query interface to it.

思考,这样一种层次模型是否可以用来存储gis数据呢,或者说是否可以重新表达矢量数据模型呢?如多尺度问题。这种方式能否表达矢量要素之间的拓扑关系呢?


那么这样认为是否可行?

这种层次模型本质上体现了分类的思想,是一种树结构,与其与多尺度结合,不如与本体结合。

它的优势在于非结构化的数据组织方式。看来要想为己所用,还是图数据库。先这样惦记着吧。

今天down了最新版本的Sedna数据库源码sedna-3.5.161,用CMake gui方式进行了编译。

编译中注意,需要将source code位置与binaries位置区分开,在将source code下建bld目录。然后CMake,一路通过,选用了vs2005编译器。编译完成后,在Debug与Release下生成了bin目录,其中就是我们需要的各个应用名称,其中se_gov.exe为数据库服务,cmd启动后在后台运行。其它的应该对应了部分sql命令,如se_cdb.exe创建表。

服务启动后,就可以配置客户端开发了。新创建的数据库文件在bin同级目录data下,以dbname_files命名。

在driver-c-debug下有我们需要的h lib与dll。简单的配置就可以进行开发了。以下为测试代码,部分被注释掉了,来自官方网站。


#include "libsedna.h" 

int _tmain(int argc, _TCHAR* argv[])
{
struct SednaConnection conn = SEDNA_CONNECTION_INITIALIZER; 
const char* url = "localhost";   
const char* db_name = "testdb";   
const char* login = "SYSTEM";   
const char* password = "MANAGER";   


//connecting to database "testdb" with login "SYSTEM", password "MANAGER"   
int res = SEconnect(&conn, url, db_name, login, password);   
if(res != SEDNA_SESSION_OPEN)    
{   
printf("Session starting failed: \n%s\n", SEgetLastErrorMsg(&conn));   
return -1;   
}  


// load data from file "categories.xml" into the document "categories"   
//res = SEexecute(&conn, "LOAD 'D:/opensource/sedna/sedna-3.5.161/examples/api/data/categories.xml' 'categories'");    
//if(res != SEDNA_BULK_LOAD_SUCCEEDED)    
//{   
// printf("Bulk load failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// // closing session to free resources   
// SEclose(&conn);   
// return -1;   
//}  


// create collection wikidb   
//res = SEexecute(&conn, "CREATE COLLECTION 'wikidb'");    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Create collection failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// // closing session   
// SEclose(&conn);   
// return -1;   
//}   


//res = SEexecute(&conn, "LOAD 'D:/opensource/sedna/sedna-3.5.161/examples/api/data/page01.xml' 'page01' 'wikidb'");    
//if(res != SEDNA_BULK_LOAD_SUCCEEDED)   
//{   
// printf("Bulk load failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// // closing session   
// SEclose(&conn);   
// return -1;   
//}  


// this query builds small HTML document    
// using data from collection 'wikidb',    
//这里定义了输出格式
const char* query = "let $c:='Category:Anarchism'\n"  
"return\n"  
" \n"  
"<html>\n"  
"<h1>{$c}</h1>\n"  
"<br/>\n"  
"<i>Parent categories:</i>\n"  
"<ul>\n"  
"{for $p in doc('categories')/categories/category[@id=$c]/parent\n"  
"return <li>{$p//@id/string()}</li>}\n"  
"</ul>\n"  
" \n"  
"<i>Articles in this category:</i>\n"  
"<ul>\n"  
"{for $a in collection('wikidb')/page[.//catlink/@href=$c]\n"  
"return <li>{$a/title/text()}</li>}\n"  
"</ul>\n"  
"</html>";   


// execute XQuery query    
res = SEexecute(&conn, query);    
if(res != SEDNA_QUERY_SUCCEEDED)    
{   
printf("Query failed: \n%s\n", SEgetLastErrorMsg(&conn));   
//closing session   
SEclose(&conn);   
return -1;   
}  
// iterate over the result sequence and retrieve the result data   
while((res = SEnext(&conn)) != SEDNA_RESULT_END)   
{   
if (res == SEDNA_ERROR)   
{   
printf("Failed to get next result item from server: \n%s\n",    
SEgetLastErrorMsg(&conn));   
//closing session   
SEclose(&conn);   
return -1;   
}   


int bytes_read = 0;
do  
{   
char buf[1024] = {0};
bytes_read = SEgetData(&conn, buf, 1024 - 1);   
if(bytes_read == SEDNA_ERROR)   
{   
printf("Failed to get result data from server: \n%s\n",    
SEgetLastErrorMsg(&conn));   
//closing session   
SEclose(&conn);   
return -1;   
}   
buf[bytes_read] = '\0';   
printf("%s", buf);   


}while(bytes_read > 0);   
printf("\n");   
}  


//索引
//const char* create_index = "CREATE INDEX 'page-by-category'\n"  
// "ON collection('wikidb')/page\n"  
// "BY .//catlink/@href AS xs:string\n";   


//res = SEexecute(&conn, create_index);    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Create index failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}  


//query =    
// "for $a in index-scan('page-by-category', 'Category:Anarchism', 'EQ')\n"  
// "return <h3>{$a/title/text()}</h3>}\n";   


execute query that uses newly create index    
//res = SEexecute(&conn, query);    
//if(res != SEDNA_QUERY_SUCCEEDED)    
//{   
// printf("Query failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}   


iterate over the result sequence and retrieve the result data   
//while((res = SEnext(&conn)) != SEDNA_RESULT_END)   
//{   
// if (res == SEDNA_ERROR)   
// {   
// printf("Failed to get next result item from server: \n%s\n",    
// SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
// }   


// int bytes_read = 0;
// char buf[1024] = {0};


// do  
// {   
// bytes_read = SEgetData(&conn, buf, 1024 - 1);   
// if(bytes_read == SEDNA_ERROR)   
// {   
// printf("Failed to get result data from server: \n%s\n",    
// SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
// }   
// buf[bytes_read] = '\0';   
// printf("%s", buf);   


// }while(bytes_read > 0);   
// printf("\n");   
//}  


//const char* update_delete = "UPDATE delete collection('wikidb')//comment";   


delete all 'comment' nodes in collection 'wikidb'   
//res = SEexecute(&conn, update_delete);    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Update failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}  


//const char* update_replace = "UPDATE\n"  
// "replace $l in \n"  
// " let $p:=collection('wikidb')/page/title\n"  
// " return\n"  
// " collection('wikidb')//link[@label != $p]\n"  
// " with <i>{$l/text()}</i>";   


replace 'link' nodes that refer to the page that    
does not exist in collection 'wikidb' on to 'i' node   
//res = SEexecute(&conn, update_replace);    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Update failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}  
//const char* update_insert =    
// "UPDATE\n"  
// "insert (<timestamp>{current-dateTime()}</timestamp>\n"  
// "<contributor>sedna-user</contributor>)\n"  
// "into collection('wikidb')/page[title='NASA']/revision";   




insert current date/time and    
contributor name 'sedna-user' in the beginning of page 'NASA'.   
//res = SEexecute(&conn, update_insert);    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Update failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}  


/*
Trigger "trigger-on-insert-link" watches if the inserted links are valid. On insertion of 'link' node into page 'summary', trigger checks if there is a page that link refers. If there is no such a page, trigger changes 'link' node that is being inserted onto 'i' node with the same content. 


*/
//const char* create_trigger_on_insert_link =    
// "CREATE TRIGGER 'trigger-on-insert-link'\n"  
// "BEFORE INSERT\n"  
// "ON collection('wikidb')/page//summary/link\n"  
// "FOR EACH NODE\n"  
// "DO\n"  
// "{\n"  
// " let $p:=collection('wikidb')/page/title\n"  
// " return\n"  
// "   if($NEW/@label != $p)\n"  
// "   then <i>{$NEW/text()}</i>\n"  
// "   else $NEW;\n"  
// "}";   


create trigger on insert   
//res = SEexecute(&conn, create_trigger_on_insert_link);    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Create trigger failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}  




/*
igger "trigger-on-delete-category" watches that category list in document 'categories' is valid. On deletion of category from the 'categories' document, the trigger deletes all references to this category in Wikipedia pages.
*/
//const char* create_trigger_on_delete_category =    
// "CREATE TRIGGER 'trigger-on-delete-category'\n"  
// "AFTER DELETE\n"  
// "ON doc('categories')/categories/category\n"  
// "FOR EACH NODE\n"  
// "DO\n"  
// "{\n"  
// "  UPDATE delete \n"  
// "      collection('wikidb')//catlink[@href=$OLD/@id];\n"  
// "  $OLD;\n"  
// "}";   


create trigger on delete   
//res = SEexecute(&conn, create_trigger_on_delete_category);    
//if(res != SEDNA_UPDATE_SUCCEEDED)    
//{   
// printf("Create trigger failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//}  


// load module from file "math.xqlib"   
//res = SEexecute(&conn, "LOAD MODULE 'D:/opensource/sedna/sedna-3.5.161/examples/api/c/math.xqlib'");    
//if(res != SEDNA_BULK_LOAD_SUCCEEDED)    
//{   
// printf("Update failed: \n%s\n", SEgetLastErrorMsg(&conn));   
// //closing session   
// SEclose(&conn);   
// return -1;   
//} 
query="import module namespace math='http://example.org/math';\n"  
"math:increment(math:square(\$math:pi))";    


// execute query that uses module   
res = SEexecute(&conn, query);    
if(res != SEDNA_QUERY_SUCCEEDED)    
{   
printf("Query failed: \n%s\n", SEgetLastErrorMsg(&conn));   
//closing session   
SEclose(&conn);   
return -1;   
}  




//closing session   
res = SEclose(&conn);   
if(res != SEDNA_SESSION_CLOSED)    
{   
printf("An error occurred while trying to close session: \n%s\n",    
SEgetLastErrorMsg(&conn));   
return -1;   
}  




return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值