Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
4859219f
Commit
4859219f
authored
Aug 21, 2001
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add 0.2 version XML files.
parent
f00caec5
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
245 additions
and
0 deletions
+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
No files found.
contrib/xml/pgxml_dom.c
0 → 100644
View file @
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
View file @
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment