Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
4859219f
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4859219f
编写于
8月 21, 2001
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add 0.2 version XML files.
上级
f00caec5
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
245 addition
and
0 deletion
+245
-0
contrib/xml/pgxml_dom.c
contrib/xml/pgxml_dom.c
+238
-0
contrib/xml/pgxml_dom.source
contrib/xml/pgxml_dom.source
+7
-0
未找到文件。
contrib/xml/pgxml_dom.c
0 → 100644
浏览文件 @
4859219f
/* Parser interface for DOM-based parser (libxml) rather than
stream-based SAX-type parser */
#include "postgres.h"
#include "fmgr.h"
/* libxml includes */
#include <libxml/xpath.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>
/* declarations */
static
void
*
pgxml_palloc
(
size_t
size
);
static
void
*
pgxml_repalloc
(
void
*
ptr
,
size_t
size
);
static
void
pgxml_pfree
(
void
*
ptr
);
static
char
*
pgxml_pstrdup
(
const
char
*
string
);
static
void
pgxml_parser_init
();
static
xmlChar
*
pgxmlNodeSetToText
(
xmlNodeSetPtr
nodeset
,
xmlDocPtr
doc
,
xmlChar
*
toptagname
,
xmlChar
*
septagname
,
int
format
);
static
xmlChar
*
pgxml_texttoxmlchar
(
text
*
textstring
);
Datum
pgxml_parse
(
PG_FUNCTION_ARGS
);
Datum
pgxml_xpath
(
PG_FUNCTION_ARGS
);
/* memory handling passthrough functions (e.g. palloc, pstrdup are
currently macros, and the others might become so...) */
static
void
*
pgxml_palloc
(
size_t
size
)
{
return
palloc
(
size
);
}
static
void
*
pgxml_repalloc
(
void
*
ptr
,
size_t
size
)
{
return
repalloc
(
ptr
,
size
);
}
static
void
pgxml_pfree
(
void
*
ptr
)
{
return
pfree
(
ptr
);
}
static
char
*
pgxml_pstrdup
(
const
char
*
string
)
{
return
pstrdup
(
string
);
}
static
void
pgxml_parser_init
()
{
/* This code should also set parser settings from user-supplied
info. Quite how these settings are made is another matter :) */
xmlMemSetup
(
pgxml_pfree
,
pgxml_palloc
,
pgxml_repalloc
,
pgxml_pstrdup
);
xmlInitParser
();
}
/* Returns true if document is well-formed */
PG_FUNCTION_INFO_V1
(
pgxml_parse
);
Datum
pgxml_parse
(
PG_FUNCTION_ARGS
)
{
/* called as pgxml_parse(document) */
xmlDocPtr
doctree
;
text
*
t
=
PG_GETARG_TEXT_P
(
0
);
/*document buffer */
int32
docsize
=
VARSIZE
(
t
)
-
VARHDRSZ
;
pgxml_parser_init
();
doctree
=
xmlParseMemory
((
char
*
)
VARDATA
(
t
),
docsize
);
if
(
doctree
==
NULL
)
{
/* xmlCleanupParser(); */
PG_RETURN_BOOL
(
false
);
/* i.e. not well-formed */
}
/* xmlCleanupParser(); */
xmlFreeDoc
(
doctree
);
PG_RETURN_BOOL
(
true
);
}
static
xmlChar
*
pgxmlNodeSetToText
(
xmlNodeSetPtr
nodeset
,
xmlDocPtr
doc
,
xmlChar
*
toptagname
,
xmlChar
*
septagname
,
int
format
)
{
/* Function translates a nodeset into a text representation */
/* iterates over each node in the set and calls xmlNodeDump to write
it to an xmlBuffer -from which an xmlChar * string is returned. */
/* each representation is surrounded by <tagname> ... </tagname> */
/* if format==0, add a newline between nodes?? */
xmlBufferPtr
buf
;
xmlChar
*
result
;
int
i
;
buf
=
xmlBufferCreate
();
if
((
toptagname
!=
NULL
)
&&
(
xmlStrlen
(
toptagname
)
>
0
))
{
xmlBufferWriteChar
(
buf
,
"<"
);
xmlBufferWriteCHAR
(
buf
,
toptagname
);
xmlBufferWriteChar
(
buf
,
">"
);
}
if
(
nodeset
!=
NULL
)
{
for
(
i
=
0
;
i
<
nodeset
->
nodeNr
;
i
++
)
{
if
((
septagname
!=
NULL
)
&&
(
xmlStrlen
(
septagname
)
>
0
))
{
xmlBufferWriteChar
(
buf
,
"<"
);
xmlBufferWriteCHAR
(
buf
,
septagname
);
xmlBufferWriteChar
(
buf
,
">"
);
}
xmlNodeDump
(
buf
,
doc
,
nodeset
->
nodeTab
[
i
],
1
,(
format
==
2
));
if
((
septagname
!=
NULL
)
&&
(
xmlStrlen
(
septagname
)
>
0
))
{
xmlBufferWriteChar
(
buf
,
"</"
);
xmlBufferWriteCHAR
(
buf
,
septagname
);
xmlBufferWriteChar
(
buf
,
">"
);
}
if
(
format
)
{
xmlBufferWriteChar
(
buf
,
"
\n
"
);
}
}
}
if
((
toptagname
!=
NULL
)
&&
(
xmlStrlen
(
toptagname
)
>
0
))
{
xmlBufferWriteChar
(
buf
,
"</"
);
xmlBufferWriteCHAR
(
buf
,
toptagname
);
xmlBufferWriteChar
(
buf
,
">"
);
}
result
=
xmlStrdup
(
buf
->
content
);
xmlBufferFree
(
buf
);
return
result
;
}
static
xmlChar
*
pgxml_texttoxmlchar
(
text
*
textstring
)
{
xmlChar
*
res
;
int32
txsize
;
txsize
=
VARSIZE
(
textstring
)
-
VARHDRSZ
;
res
=
(
xmlChar
*
)
palloc
(
txsize
+
1
);
memcpy
((
char
*
)
res
,
VARDATA
(
textstring
),
txsize
);
res
[
txsize
]
=
'\0'
;
return
res
;
}
PG_FUNCTION_INFO_V1
(
pgxml_xpath
);
Datum
pgxml_xpath
(
PG_FUNCTION_ARGS
)
{
xmlDocPtr
doctree
;
xmlXPathContextPtr
ctxt
;
xmlXPathObjectPtr
res
;
xmlChar
*
xpath
,
*
xpresstr
,
*
toptag
,
*
septag
;
xmlXPathCompExprPtr
comppath
;
int32
docsize
,
ressize
;
text
*
t
,
*
xpres
;
t
=
PG_GETARG_TEXT_P
(
0
);
/*document buffer */
xpath
=
pgxml_texttoxmlchar
(
PG_GETARG_TEXT_P
(
1
));
/* XPath expression */
toptag
=
pgxml_texttoxmlchar
(
PG_GETARG_TEXT_P
(
2
));
septag
=
pgxml_texttoxmlchar
(
PG_GETARG_TEXT_P
(
3
));
docsize
=
VARSIZE
(
t
)
-
VARHDRSZ
;
pgxml_parser_init
();
doctree
=
xmlParseMemory
((
char
*
)
VARDATA
(
t
),
docsize
);
if
(
doctree
==
NULL
)
{
/* not well-formed */
PG_RETURN_NULL
();
}
ctxt
=
xmlXPathNewContext
(
doctree
);
ctxt
->
node
=
xmlDocGetRootElement
(
doctree
);
/* compile the path */
comppath
=
xmlXPathCompile
(
xpath
);
if
(
comppath
==
NULL
)
{
elog
(
NOTICE
,
"XPath syntax error"
);
xmlFreeDoc
(
doctree
);
pfree
((
void
*
)
xpath
);
PG_RETURN_NULL
();
}
/* Now evaluate the path expression. */
res
=
xmlXPathCompiledEval
(
comppath
,
ctxt
);
xmlXPathFreeCompExpr
(
comppath
);
if
(
res
==
NULL
)
{
xmlFreeDoc
(
doctree
);
pfree
((
void
*
)
xpath
);
PG_RETURN_NULL
();
/* seems appropriate */
}
/* now we dump this node, ?surrounding by tags? */
/* To do this, we look first at the type */
switch
(
res
->
type
)
{
case
XPATH_NODESET
:
xpresstr
=
pgxmlNodeSetToText
(
res
->
nodesetval
,
doctree
,
toptag
,
septag
,
0
);
break
;
case
XPATH_STRING
:
xpresstr
=
xmlStrdup
(
res
->
stringval
);
break
;
default:
elog
(
NOTICE
,
"Unsupported XQuery result: %d"
,
res
->
type
);
xpresstr
=
xmlStrdup
(
"<unsupported/>"
);
}
/* Now convert this result back to text */
ressize
=
strlen
(
xpresstr
);
xpres
=
(
text
*
)
palloc
(
ressize
+
VARHDRSZ
);
memcpy
(
VARDATA
(
xpres
),
xpresstr
,
ressize
);
VARATT_SIZEP
(
xpres
)
=
ressize
+
VARHDRSZ
;
/* Free various storage */
xmlFreeDoc
(
doctree
);
pfree
((
void
*
)
xpath
);
xmlFree
(
xpresstr
);
PG_RETURN_TEXT_P
(
xpres
);
}
contrib/xml/pgxml_dom.source
0 → 100644
浏览文件 @
4859219f
--SQL for XML parser
CREATE FUNCTION pgxml_parse(text) RETURNS bool
AS '_OBJWD_/pgxml_dom_DLSUFFIX_' LANGUAGE 'c' WITH (isStrict);
CREATE FUNCTION pgxml_xpath(text,text,text,text) RETURNS text
AS '_OBJWD_/pgxml_dom_DLSUFFIX_' LANGUAGE 'c' WITH (isStrict);
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录