/* $Id: LibXML.xs,v 1.73 2002/03/15 12:34:50 phish Exp $ */
#ifdef __cplusplus
extern "C" {
#endif
/* perl stuff */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
/* libxml2 stuff */
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/HTMLparser.h>
#include <libxml/HTMLtree.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xmlIO.h>
/* #include <libxml/debugXML.h> */
#include <libxml/xmlerror.h>
#include <libxml/xinclude.h>
#include <libxml/valid.h>
/* XML::LibXML stuff */
#include "perl-libxml-mm.h"
#include "dom.h"
#include "xpath.h"
#ifdef __cplusplus
}
#endif
#ifdef VMS
extern int xmlDoValidityCheckingDefaultVal;
#define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
extern int xmlSubstituteEntitiesDefaultVal;
#define xmlSubstituteEntitiesDefaultValue xmlSubstituteEntitiesDefaultVal
#else
extern int xmlDoValidityCheckingDefaultValue;
extern int xmlSubstituteEntitiesDefaultValue;
#endif
extern int xmlGetWarningsDefaultValue;
extern int xmlKeepBlanksDefaultValue;
extern int xmlLoadExtDtdDefaultValue;
extern int xmlPedanticParserDefaultValue;
#define SET_CB(cb, fld) \
RETVAL = cb ? newSVsv(cb) : &PL_sv_undef;\
if (SvOK(fld)) {\
if (cb) {\
if (cb != fld) {\
sv_setsv(cb, fld);\
}\
}\
else {\
cb = newSVsv(fld);\
}\
}\
else {\
if (cb) {\
SvREFCNT_dec(cb);\
cb = NULL;\
}\
}
#define TEST_PERL_FLAG(flag) \
SvTRUE(perl_get_sv(flag, FALSE)) ? 1 : 0
static SV * LibXML_match_cb = NULL;
static SV * LibXML_read_cb = NULL;
static SV * LibXML_open_cb = NULL;
static SV * LibXML_close_cb = NULL;
static SV * LibXML_error = NULL;
/* this should keep the default */
static xmlExternalEntityLoader LibXML_old_ext_ent_loader = NULL;
xmlParserInputPtr
LibXML_load_external_entity(
const char * URL,
const char * ID,
xmlParserCtxtPtr ctxt)
{
SV * self;
HV * real_obj;
SV ** func;
int count;
SV * results;
STRLEN results_len;
const char * results_pv;
xmlParserInputBufferPtr input_buf;
if (ctxt->_private == NULL) {
return xmlNewInputFromFile(ctxt, URL);
}
if (URL == NULL) {
URL = "";
}
if (ID == NULL) {
ID = "";
}
self = (SV *)ctxt->_private;
real_obj = (HV *)SvRV(self);
func = hv_fetch(real_obj, "ext_ent_handler", 15, 0);
if (func) {
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP) ;
XPUSHs(sv_2mortal(newSVpv((char*)URL, 0)));
XPUSHs(sv_2mortal(newSVpv((char*)ID, 0)));
PUTBACK;
count = perl_call_sv(*func, G_SCALAR);
SPAGAIN;
if (!count) {
croak("external entity handler did not return a value");
}
results = POPs;
results_pv = SvPV(results, results_len);
input_buf = xmlParserInputBufferCreateMem(
results_pv,
results_len,
XML_CHAR_ENCODING_NONE
);
FREETMPS;
LEAVE;
return xmlNewIOInputStream(ctxt, input_buf, XML_CHAR_ENCODING_NONE);
}
else {
if (URL == NULL) {
return NULL;
}
return xmlNewInputFromFile(ctxt, URL);
}
}
int
LibXML_input_match(char const * filename)
{
int results = 0;
SV * global_cb;
SV * callback = NULL;
if (LibXML_match_cb && SvTRUE(LibXML_match_cb)) {
callback = LibXML_match_cb;
}
else if ((global_cb = perl_get_sv("XML::LibXML::match_cb", FALSE))
&& SvTRUE(global_cb)) {
callback = global_cb;
}
if (callback) {
int count;
SV * res;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv((char*)filename, 0)));
PUTBACK;
count = perl_call_sv(callback, G_SCALAR);
SPAGAIN;
if (count != 1) {
croak("match callback must return a single value");
}
res = POPs;
if (SvTRUE(res)) {
results = 1;
}
PUTBACK;
FREETMPS;
LEAVE;
}
return results;
}
void *
LibXML_input_open(char const * filename)
{
SV * results;
SV * global_cb;
SV * callback = NULL;
if (LibXML_open_cb && SvTRUE(LibXML_open_cb)) {
callback = LibXML_open_cb;
}
else if ((global_cb = perl_get_sv("XML::LibXML::open_cb", FALSE))
&& SvTRUE(global_cb)) {
callback = global_cb;
}
if (callback) {
int count;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv((char*)filename, 0)));
PUTBACK;
count = perl_call_sv(callback, G_SCALAR);
SPAGAIN;
if (count != 1) {
croak("open callback must return a single value");
}
results = POPs;
SvREFCNT_inc(results);
PUTBACK;
FREETMPS;
LEAVE;
}
return (void *)results;
}
int
LibXML_input_read(void * context, char * buffer, int len)
{
SV * results = NULL;
STRLEN res_len = 0;
const char * output;
SV * global_cb;
SV * callback = NULL;
SV * ctxt = (SV *)context;
if (LibXML_read_cb && SvTRUE(LibXML_read_cb)) {
callback = LibXML_read_cb;
}
else if ((global_cb = perl_get_sv("XML::LibXML::read_cb", FALSE))
&& SvTRUE(global_cb)) {
callback = global_cb;
}
if (callback) {
int count;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
EXTEND(SP, 2);
PUSHs(ctxt);
PUSHs(sv_2mortal(newSViv(len)));
PUTBACK;
count = perl_call_sv(callback, G_SCALAR);
SPAGAIN;
if (count != 1) {
croak("read callback must return a single value");
}
output = POPp;
if (output != NULL) {
res_len = strlen(output);
if (res_len) {
strncpy(buffer, output, res_len);
}
else {
buffer[0] = 0;
}
}
FREETMPS;
LEAVE;
}
/* warn("read, asked for: %d, returning: [%d] %s\n", len, res_len, buffer); */
return res_len;
}
void
LibXML_input_close(void * context)
{
SV * global_cb;
SV * callback = NULL;
SV * ctxt = (SV *)context;
if (LibXML_close_cb && SvTRUE(LibXML_close_cb)) {
callback = LibXML_close_cb;
}
else if ((global_cb = perl_get_sv("XML::LibXML::close_cb", FALSE))
&& SvTRUE(global_cb)) {
callback = global_cb;
}
if (callback) {
int count;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
EXTEND(SP, 1);
PUSHs(ctxt);
PUTBACK;
count = perl_call_sv(callback, G_SCALAR);
SPAGAIN;
SvREFCNT_dec(ctxt);
if (!count) {
croak("close callback failed");
}
PUTBACK;
FREETMPS;
LEAVE;
}
}
void
LibXML_error_handler(void * ctxt, const char * msg, ...)
{
va_list args;
SV * sv;
sv = NEWSV(0,512);
va_start(args, msg);
sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL);
va_end(args);
if (LibXML_error != NULL) {
sv_catsv(LibXML_error, sv); /* remember the last error */
}
else {
croak(SvPV(sv, PL_na));
}
SvREFCNT_dec(sv);
}
void
LibXML_validity_error(void * ctxt, const char * msg, ...)
{
va_list args;
SV * sv;
sv = NEWSV(0,512);
va_start(args, msg);
sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL);
va_end(args);
if (LibXML_error != NULL) {
sv_catsv(LibXML_error, sv); /* remember the last error */
}
else {
croak(SvPV(sv, PL_na));
}
SvREFCNT_dec(sv);
}
void
LibXML_validity_warning(void * ctxt, const char * msg, ...)
{
va_list args;
STRLEN len;
SV * sv;
sv = NEWSV(0,512);
va_start(args, msg);
sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL);
va_end(args);
warn(SvPV(sv, len));
SvREFCNT_dec(sv);
}
int
LibXML_read_perl (SV * ioref, char * buffer, int len)
{
dSP;
int cnt;
SV * read_results;
STRLEN read_length;
char * chars;
SV * tbuff = NEWSV(0,len);
SV * tsize = newSViv(len);
ENTER;
SAVETMPS;
PUSHMARK(SP);
EXTEND(SP, 3);
PUSHs(ioref);
PUSHs(sv_2mortal(tbuff));
PUSHs(sv_2mortal(tsize));
PUTBACK;
if (sv_isobject(ioref)) {
cnt = perl_call_method("read", G_SCALAR);
}
else {
cnt = perl_call_pv("__read", G_SCALAR);
}
SPAGAIN;
if (cnt != 1) {
croak("read method call failed");
}
read_results = POPs;
if (!SvOK(read_results)) {
croak("read error");
}
read_length = SvIV(read_results);
chars = SvPV(tbuff, read_length);
strncpy(buffer, chars, read_length);
FREETMPS;
LEAVE;
return read_length;
}
xmlDocPtr
LibXML_parse_stream(SV * self, SV * ioref, char * directory)
{
xmlDocPtr doc = NULL;
xmlParserCtxtPtr ctxt;
int well_formed = 0;
int valid = 0;
char buffer[1024];
int read_length;
int ret = -1;
char current_dir[512];
if (directory == NULL) {
if (getcwd(current_dir, 512) != 0) {
directory = current_dir;
}
else {
warn("couldn't get current directory: %s\n", strerror(errno));
}
}
read_length = LibXML_read_perl(ioref, buffer, 4);
if (read_length > 0) {
ctxt = xmlCreatePushParserCtxt(NULL, NULL, buffer, read_length, NULL);
if (ctxt == NULL) {
croak("Could not create push parser context: %s", strerror(errno));
}
ctxt->directory = directory;
ctxt->_private = (void*)self;
while(read_length = LibXML_read_perl(ioref, buffer, 1024)) {
xmlParseChunk(ctxt, buffer, read_length, 0);
}
ret = xmlParseChunk(ctxt, buffer, 0, 1);
ctxt->directory = NULL;
/* jsut being paranoid */
if ( ret == 0 ) {
doc = ctxt->myDoc;
well_formed = ctxt->wellFormed;
xmlFreeParserCtxt(ctxt);
}
}
else {
croak( "Empty Stream" );
}
if (!well_formed || (xmlDoValidityCheckingDefaultValue && !valid && (doc->intSubset || doc->extSubset) )) {
xmlFreeDoc(doc);
return NULL;
}
/* this should be done by libxml2 !? */
if (doc->encoding == NULL) {
doc->encoding = xmlStrdup((const xmlChar*)"utf-8");
}
if ( directory == NULL ) {
STRLEN len;
SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)doc));
doc->URL = xmlStrdup((const xmlChar*)SvPV(newURI, len));
} else {
doc->URL = xmlStrdup((const xmlChar*)directory);
}
return doc;
}
xmlDocPtr
LibXML_parse_html_stream(SV * self, SV * ioref)
{
xmlDocPtr doc = NULL;
htmlParserCtxtPtr ctxt;
int well_formed = 0;
char buffer[1024];
int read_length;
int ret = -1;
read_length = LibXML_read_perl(ioref, buffer, 4);
if (read_length > 0) {
ctxt = htmlCreatePushParserCtxt(NULL, NULL, buffer, read_length, NULL, XML_CHAR_ENCODING_NONE);
if (ctxt == NULL) {
croak("Could not create html push parser context: %s", strerror(errno));
}
ctxt->_private = (void*)self;
while(read_length = LibXML_read_perl(ioref, buffer, 1024)) {
ret = htmlParseChunk(ctxt, buffer, read_length, 0);
if ( ret != 0 ) {
break;
}
}
ret = htmlParseChunk(ctxt, buffer, 0, 1);
if ( ret == 0 ) {
doc = ctxt->myDoc;
well_formed = ctxt->wellFormed;
htmlFreeParserCtxt(ctxt);
}
}
else {
croak( "Empty Stream" );
}
if (!well_formed) {
xmlFreeDoc(doc);
return NULL;
}
return doc;
}
void
LibXML_cleanup_parser() {
xmlSubstituteEntitiesDefaultValue = 1;
xmlKeepBlanksDefaultValue = 1;
xmlGetWarningsDefaultValue = 0;
xmlLoadExtDtdDefaultValue = 5;
xmlPedanticParserDefaultValue = 0;
xmlDoValidityCheckingDefaultValue = 0;
xmlSetGenericErrorFunc(NULL, NULL);
}
void
LibXML_init_parser( SV * self ) {
/* we fetch all switches and callbacks from the hash */
xmlSetGenericErrorFunc(PerlIO_stderr(),
(xmlGenericErrorFunc)LibXML_error_handler);
if ( self != NULL ) {
/* first fetch the values from the hash */
HV* real_obj = (HV *)SvRV(self);
SV** item = NULL;
SV * RETVAL = NULL; /* dummy for the stupid macro */
item = hv_fetch( real_obj, "XML_LIBXML_VALIDATION", 21, 0 );
xmlDoValidityCheckingDefaultValue = item != NULL && SvTRUE(*item) ? 1 : 0;
item = hv_fetch( real_obj, "XML_LIBXML_EXPAND_ENTITIES", 26, 0 );
xmlSubstituteEntitiesDefaultValue = item != NULL && SvTRUE(*item) ? 1 : 0;
item = hv_fetch( real_obj, "XML_LIBXML_KEEP_BLANKS", 22, 0 );
xmlKeepBlanksDefaultValue = item != NULL && SvTRUE(*item) ? 1 : 0;
item = hv_fetch( real_obj, "XML_LIBXML_PEDANTIC", 19, 0 );
xmlPedanticParserDefaultValue = item != NULL && SvTRUE(*item) ? 1 : 0;
item = hv_fetch( real_obj, "XML_LIBXML_EXT_DTD", 18, 0 );
if ( item != NULL && SvTRUE(*item) )
xmlLoadExtDtdDefaultValue |= 1;
else
xmlLoadExtDtdDefaultValue ^= 1;
item = hv_fetch( real_obj, "XML_LIBXML_COMPLETE_ATTR", 24, 0 );
if (item != NULL && SvTRUE(*item))
xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
else
xmlLoadExtDtdDefaultValue ^= XML_COMPLETE_ATTRS;
/* now fetch the callbacks */
item = hv_fetch( real_obj, "XML_LIBXML_READ_CB", 18, 0 );
if ( item != NULL && SvTRUE(*item))
LibXML_read_cb= *item;
item = hv_fetch( real_obj, "XML_LIBXML_MATCH_CB", 19, 0 );
if ( item != NULL && SvTRUE(*item))
LibXML_match_cb= *item;
item = hv_fetch( real_obj, "XML_LIBXML_OPEN_CB", 18, 0 );
if ( item != NULL && SvTRUE(*item))
LibXML_open_cb = *item;
item = hv_fetch( real_obj, "XML_LIBXML_CLOSE_CB", 19, 0 );
if ( item != NULL && SvTRUE(*item))
LibXML_close_cb = *item;
}
return;
/* LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader(); */
/* warn(" init parser callbacks!\n"); */
xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXML_input_match,
(xmlInputOpenCallback) LibXML_input_open,
(xmlInputReadCallback) LibXML_input_read,
(xmlInputCloseCallback) LibXML_input_close);
xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_load_external_entity );
}
void
LibXML_cleanup_callbacks() {
return;
/* warn(" cleanup parser callbacks!\n"); */
xmlCleanupInputCallbacks();
xmlRegisterDefaultInputCallbacks();
/* if ( LibXML_old_ext_ent_loader != NULL ) { */
/* xmlSetExternalEntityLoader( NULL ); */
/* xmlSetExternalEntityLoader( LibXML_old_ext_ent_loader ); */
/* LibXML_old_ext_ent_loader = NULL; */
/* } */
/* xsltSetGenericDebugFunc(NULL, NULL); */
}
MODULE = XML::LibXML PACKAGE = XML::LibXML
PROTOTYPES: DISABLE
BOOT:
LIBXML_TEST_VERSION
xmlInitParser();
xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXML_input_match,
(xmlInputOpenCallback) LibXML_input_open,
(xmlInputReadCallback) LibXML_input_read,
(xmlInputCloseCallback) LibXML_input_close);
xmlSetGenericErrorFunc( NULL ,
(xmlGenericErrorFunc)LibXML_error_handler);
xmlDoValidityCheckingDefaultValue = 0;
xmlSubstituteEntitiesDefaultValue = 1;
xmlGetWarningsDefaultValue = 0;
xmlKeepBlanksDefaultValue = 1;
xmlLoadExtDtdDefaultValue = 5;
xmlPedanticParserDefaultValue = 0;
void
END()
CODE:
xmlCleanupParser();
int
XML_ELEMENT_NODE()
ALIAS:
XML::LibXML::ELEMENT_NODE = 1
CODE:
RETVAL = 1;
OUTPUT:
RETVAL
int
XML_ATTRIBUTE_NODE()
ALIAS:
XML::LibXML::ATTRIBUTE_NODE = 1
CODE:
RETVAL = 2;
OUTPUT:
RETVAL
int
XML_TEXT_NODE()
ALIAS:
XML::LibXML::TEXT_NODE = 1
CODE:
RETVAL = 3;
OUTPUT:
RETVAL
int
XML_CDATA_SECTION_NODE()
ALIAS:
XML::LibXML::CDATA_SECTION_NODE = 1
CODE:
RETVAL = 4;
OUTPUT:
RETVAL
int
XML_ENTITY_REF_NODE()
ALIAS:
XML::LibXML::ENTITY_REFERENCE_NODE = 1
CODE:
RETVAL = 5;
OUTPUT:
RETVAL
int
XML_ENTITY_NODE()
ALIAS:
XML::LibXML::ENTITY_NODE = 1
CODE:
RETVAL = 6;
OUTPUT:
RETVAL
int
XML_PI_NODE()
ALIAS:
XML::LibXML::PROCESSING_INSTRUCTION_NODE = 1
CODE:
RETVAL = 7;
OUTPUT:
RETVAL
int
XML_COMMENT_NODE()
ALIAS:
XML::LibXML::COMMENT_NODE = 1
CODE:
RETVAL = 8;
OUTPUT:
RETVAL
int
XML_DOCUMENT_NODE()
ALIAS:
XML::LibXML::DOCUMENT_NODE = 1
CODE:
RETVAL = 9;
OUTPUT:
RETVAL
int
XML_DOCUMENT_TYPE_NODE()
ALIAS:
XML::LibXML::DOCUMENT_TYPE_NODE = 1
CODE:
RETVAL = 10;
OUTPUT:
RETVAL
int
XML_DOCUMENT_FRAG_NODE()
ALIAS:
XML::LibXML::DOCUMENT_FRAGMENT_NODE = 1
CODE:
RETVAL = 11;
OUTPUT:
RETVAL
int
XML_NOTATION_NODE()
ALIAS:
XML::LibXML::NOTATION_NODE = 1
CODE:
RETVAL = 12;
OUTPUT:
RETVAL
int
XML_HTML_DOCUMENT_NODE()
ALIAS:
XML::LibXML::HTML_DOCUMENT_NODE = 1
CODE:
RETVAL = 13;
OUTPUT:
RETVAL
int
XML_DTD_NODE()
ALIAS:
XML::LibXML::DTD_NODE = 1
CODE:
RETVAL = 14;
OUTPUT:
RETVAL
int
XML_ELEMENT_DECL()
ALIAS:
XML::LibXML::ELEMENT_DECLARATION = 1
CODE:
RETVAL = 15;
OUTPUT:
RETVAL
int
XML_ATTRIBUTE_DECL()
ALIAS:
XML::LibXML::ATTRIBUTE_DECLARATION = 1
CODE:
RETVAL = 16;
OUTPUT:
RETVAL
int
XML_ENTITY_DECL()
ALIAS:
XML::LibXML::ENTITY_DECLARATION = 1
CODE:
RETVAL = 17;
OUTPUT:
RETVAL
int
XML_NAMESPACE_DECL()
ALIAS:
XML::LibXML::NAMESPACE_DECLARATION = 1
CODE:
RETVAL = 18;
OUTPUT:
RETVAL
int
XML_XINCLUDE_START()
ALIAS:
XML::LibXML::XINCLUDE_START = 1
CODE:
RETVAL = 19;
OUTPUT:
RETVAL
int
XML_XINCLUDE_END()
ALIAS:
XML::LibXML::XINCLUDE_END = 1
CODE:
RETVAL = 20;
OUTPUT:
RETVAL
char *
get_last_error(CLASS)
char * CLASS
PREINIT:
STRLEN len;
CODE:
RETVAL = NULL;
if (LibXML_error != NULL) {
RETVAL = SvPV(LibXML_error, len);
}
OUTPUT:
RETVAL
SV*
_parse_string(self, string, directory = NULL)
SV * self
SV * string
char * directory
PREINIT:
xmlParserCtxtPtr ctxt;
char * CLASS = "XML::LibXML::Document";
STRLEN len;
char * ptr;
int well_formed;
int valid;
int ret;
xmlDocPtr real_dom;
ProxyObject * proxy;
HV* real_obj = (HV *)SvRV(self);
SV** item = NULL;
CODE:
ptr = SvPV(string, len);
if (len == 0) {
croak("Empty string");
}
ctxt = xmlCreateMemoryParserCtxt(ptr, len);
if (ctxt == NULL) {
croak("Couldn't create memory parser context: %s", strerror(errno));
}
ctxt->directory = directory;
# warn( "context created\n");
ctxt->_private = (void*)self;
LibXML_error = NEWSV(0, 512);
sv_setpvn(LibXML_error, "", 0);
# warn( "context initialized \n");
LibXML_init_parser(self);
ret = xmlParseDocument(ctxt);
# warn( "document parsed \n");
ctxt->directory = NULL;
well_formed = ctxt->wellFormed;
valid = ctxt->valid;
real_dom = ctxt->myDoc;
xmlFreeParserCtxt(ctxt);
sv_2mortal(LibXML_error);
if ( directory == NULL ) {
STRLEN len;
SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)real_dom));
real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, len));
} else {
real_dom->URL = xmlStrdup((const xmlChar*)directory);
}
if (!well_formed || (xmlDoValidityCheckingDefaultValue && !valid && (real_dom->intSubset || real_dom->extSubset) )) {
xmlFreeDoc(real_dom);
RETVAL = &PL_sv_undef;
croak(SvPV(LibXML_error, len));
}
else {
STRLEN n_a;
# ok check the xincludes
item = hv_fetch( real_obj, "XML_LIBXML_EXPAND_XINCLUDE", 26, 0 );
if ( item != NULL && SvTRUE(*item) ) {
# warn( "xinclude\n" );
xmlXIncludeProcess(real_dom);
}
RETVAL = nodeToSv((xmlNodePtr)real_dom);
setSvNodeExtra(RETVAL,RETVAL);
}
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
OUTPUT:
RETVAL
SV*
_parse_fh(self, fh, directory = NULL)
SV * self
SV * fh
char * directory
PREINIT:
char * CLASS = "XML::LibXML::Document";
STRLEN len;
xmlDocPtr real_dom;
ProxyObject* proxy;
CODE:
LibXML_error = NEWSV(0, 512);
sv_setpvn(LibXML_error, "", 0);
LibXML_init_parser(self);
real_dom = LibXML_parse_stream(self, fh, directory);
sv_2mortal(LibXML_error);
if (real_dom == NULL) {
RETVAL = &PL_sv_undef;
croak(SvPV(LibXML_error, len));
}
else {
STRLEN n_a;
HV* real_self = (HV*)SvRV(self);
SV** item;
# ok check the xincludes
item = hv_fetch( real_self, "XML_LIBXML_EXPAND_XINCLUDE", 26, 0 );
if ( item != NULL && SvTRUE(*item) )
xmlXIncludeProcess(real_dom);
RETVAL = nodeToSv((xmlNodePtr)real_dom);
setSvNodeExtra(RETVAL,RETVAL);
}
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
OUTPUT:
RETVAL
SV*
_parse_file(self, filename)
SV * self
const char * filename
PREINIT:
xmlParserCtxtPtr ctxt;
char * CLASS = "XML::LibXML::Document";
int well_formed = 0;
int valid = 0;
STRLEN len;
xmlDocPtr real_dom = NULL;
ProxyObject * proxy = NULL;
CODE:
LibXML_init_parser(self);
ctxt = xmlCreateFileParserCtxt(filename);
if (ctxt == NULL) {
croak("Could not create file parser context for file '%s' : %s", filename, strerror(errno));
}
ctxt->_private = (void*)self;
LibXML_error = NEWSV(0, 512);
sv_setpvn(LibXML_error, "", 0);
xmlParseDocument(ctxt);
well_formed = ctxt->wellFormed;
valid = ctxt->valid;
real_dom = ctxt->myDoc;
xmlFreeParserCtxt(ctxt);
sv_2mortal(LibXML_error);
if (!well_formed || (xmlDoValidityCheckingDefaultValue && !valid && (real_dom->intSubset || real_dom->extSubset) )) {
xmlFreeDoc(real_dom);
RETVAL = &PL_sv_undef ;
croak(SvPV(LibXML_error, len));
}
else {
HV* real_self = (HV*)SvRV(self);
SV** item = NULL;
# ok check the xincludes
item = hv_fetch( real_self, "XML_LIBXML_EXPAND_XINCLUDE", 26, 0 );
if ( item != NULL && SvTRUE(*item) ) {
# warn( "xincludes\n" );
xmlXIncludeProcess(real_dom);
}
RETVAL = nodeToSv((xmlNodePtr)real_dom);
setSvNodeExtra(RETVAL,RETVAL);
}
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
OUTPUT:
RETVAL
SV*
parse_html_string(self, string)
SV * self
SV * string
PREINIT:
htmlParserCtxtPtr ctxt;
char * CLASS = "XML::LibXML::Document";
STRLEN len;
char * ptr;
int well_formed;
int ret;
xmlDocPtr real_dom;
ProxyObject * proxy;
CODE:
ptr = SvPV(string, len);
if (len == 0) {
croak("Empty string");
}
LibXML_error = NEWSV(0, 512);
sv_setpvn(LibXML_error, "", 0);
LibXML_init_parser(self);
real_dom = htmlParseDoc((xmlChar*)ptr, NULL);
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
sv_2mortal(LibXML_error);
if (!real_dom || ((*SvPV(LibXML_error, len)) != '\0')) {
RETVAL = &PL_sv_undef;
croak(SvPV(LibXML_error, len));
}
else {
STRLEN n_a;
SV * newURI = newSVpvf("unknown-%12.12d", real_dom);
real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, n_a));
SvREFCNT_dec(newURI);
RETVAL = nodeToSv((xmlNodePtr)real_dom);
setSvNodeExtra(RETVAL,RETVAL);
}
OUTPUT:
RETVAL
SV*
parse_html_fh(self, fh)
SV * self
SV * fh
PREINIT:
char * CLASS = "XML::LibXML::Document";
STRLEN len;
xmlDocPtr real_dom;
CODE:
LibXML_error = NEWSV(0, 512);
sv_setpvn(LibXML_error, "", 0);
LibXML_init_parser(self);
real_dom = LibXML_parse_html_stream(self, fh);
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
sv_2mortal(LibXML_error);
if (!real_dom || ((*SvPV(LibXML_error, len)) != '\0')) {
RETVAL = &PL_sv_undef;
croak(SvPV(LibXML_error, len));
}
else {
STRLEN n_a;
SV * newURI = newSVpvf("unknown-%12.12d", real_dom);
real_dom->URL = xmlStrdup((const xmlChar*)SvPV(newURI, n_a));
SvREFCNT_dec(newURI);
RETVAL = nodeToSv((xmlNodePtr)real_dom);
setSvNodeExtra(RETVAL,RETVAL);
}
OUTPUT:
RETVAL
SV*
parse_html_file(self, filename)
SV * self
const char * filename
PREINIT:
char * CLASS = "XML::LibXML::Document";
STRLEN len;
xmlDocPtr real_dom;
ProxyObject * proxy;
CODE:
LibXML_error = NEWSV(0, 512);
sv_setpvn(LibXML_error, "", 0);
LibXML_init_parser(self);
real_dom = htmlParseFile((char*)filename, NULL);
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
sv_2mortal(LibXML_error);
if (!real_dom) {
RETVAL = &PL_sv_undef ;
croak(SvPV(LibXML_error, len));
}
else {
RETVAL = nodeToSv( (xmlNodePtr)real_dom );
setSvNodeExtra(RETVAL,RETVAL);
}
OUTPUT:
RETVAL
SV*
_parse_xml_chunk( self, svchunk, encoding="UTF-8" )
SV * self
SV * svchunk
char * encoding
PREINIT:
char * CLASS = "XML::LibXML::DocumentFragment";
xmlChar *chunk;
xmlNodePtr rv = NULL;
xmlNodePtr fragment= NULL;
ProxyObject *ret=NULL;
xmlNodePtr rv_end = NULL;
char * ptr;
STRLEN len;
CODE:
if ( encoding == NULL ) encoding = "UTF-8";
ptr = SvPV(svchunk, len);
if (len == 0) {
croak("Empty string");
}
/* encode the chunk to UTF8 */
chunk = Sv2C(svchunk, (const xmlChar*)encoding);
if ( chunk != NULL ) {
LibXML_error = sv_2mortal(newSVpv("", 0));
LibXML_init_parser(self);
rv = domReadWellBalancedString( NULL, chunk );
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
if ( rv != NULL ) {
/* now we append the nodelist to a document
fragment which is unbound to a Document!!!! */
# warn( "good chunk, create fragment" );
/* step 1: create the fragment */
fragment = xmlNewDocFragment( NULL );
RETVAL = nodeToSv(fragment);
setSvNodeExtra(RETVAL,RETVAL);
/* step 2: set the node list to the fragment */
fragment->children = rv;
rv->parent = fragment;
rv_end = rv;
while ( rv_end != NULL ) {
fragment->last = rv_end;
rv_end->parent = fragment;
rv_end = rv_end->next;
}
}
else {
# warn( "bad chunk" );
XSRETURN_UNDEF;
}
/* free the chunk we created */
xmlFree( chunk );
}
OUTPUT:
RETVAL
void
processXIncludes( self, dom )
SV * self
SV * dom
PREINIT:
xmlDocPtr real_dom = (xmlDocPtr)((ProxyObject*)SvIV((SV*)SvRV(dom)))->object;
CODE:
# first init the stuff for the parser
LibXML_init_parser(self);
xmlXIncludeProcess(real_dom);
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
SV*
encodeToUTF8( encoding, string )
const char * encoding
SV * string
PREINIT:
xmlChar * realstring;
xmlChar * tstr;
CODE:
xs_warn( "encoding start" );
realstring = Sv2C(string,(xmlChar*) encoding);
if ( realstring != NULL ) {
RETVAL = C2Sv(realstring, NULL);
xmlFree( realstring );
#ifdef HAVE_UTF8
SvUTF8_on(RETVAL);
#endif
}
else {
XSRETURN_UNDEF;
}
xs_warn( "encoding done" );
OUTPUT:
RETVAL
SV*
decodeFromUTF8( encoding, string )
const char * encoding
SV* string
PREINIT:
xmlChar * tstr;
xmlChar * realstring;
CODE:
xs_warn( "decoding start" );
#ifdef HAVE_UTF8
if ( SvUTF8(string) ) {
#endif
realstring = Sv2C(string,(const xmlChar*)"UTF8" );
if ( realstring != NULL ) {
tstr = (xmlChar*)domDecodeString( (const char*)encoding,
(const xmlChar*)realstring );
if ( tstr != NULL ) {
RETVAL = C2Sv((const xmlChar*)tstr,(const xmlChar*)encoding);
xmlFree( tstr );
}
else {
XSRETURN_UNDEF;
}
xmlFree( realstring );
}
else {
XSRETURN_UNDEF;
}
#ifdef HAVE_UTF8
}
else {
XSRETURN_UNDEF;
}
#endif
xs_warn( "decoding done" );
OUTPUT:
RETVAL
MODULE = XML::LibXML PACKAGE = XML::LibXML::Document
void
DESTROY(self)
ProxyObject* self
CODE:
if ( self->object != NULL ) {
if ( self->extra != NULL && SvREFCNT( self->extra ) > 1 ) {
SvREFCNT_dec( self->extra );
# warn( "TWO Document nodes" );
} else {
xmlFreeDoc((xmlDocPtr)self->object);
# warn( "REAL DOCUMENT DROP SUCCEEDS" );
}
}
self->object = NULL;
Safefree( self );
SV *
toString(self, format=0)
ProxyObject* self
int format
PREINIT:
xmlDocPtr real_dom;
xmlChar *result=NULL;
int len=0;
CODE:
real_dom = (xmlDocPtr)self->object;
if ( format <= 0 ) {
# warn( "use no formated toString!" );
xmlDocDumpMemory(real_dom, &result, &len);
}
else {
int t_indent_var = xmlIndentTreeOutput;
# warn( "use formated toString!" );
xmlIndentTreeOutput = 1;
xmlDocDumpFormatMemory( real_dom, &result, &len, format );
xmlIndentTreeOutput = t_indent_var;
}
if (result == NULL) {
# warn("Failed to convert doc to string");
RETVAL = &PL_sv_undef;
} else {
# warn("%s, %d\n",result, len);
RETVAL = newSVpvn((char *)result, (STRLEN)len);
xmlFree(result);
#ifdef HAVE_UTF8
xs_warn( "use utf8" );
SvUTF8_on(RETVAL);
#endif
}
OUTPUT:
RETVAL
SV *
toStringHTML(self)
ProxyObject* self
PREINIT:
xmlDocPtr real_dom;
xmlChar *result=NULL;
int len=0;
CODE:
real_dom = (xmlDocPtr)self->object;
# warn( "use no formated toString!" );
htmlDocDumpMemory(real_dom, &result, &len);
if (result == NULL) {
# warn("Failed to convert doc to string");
RETVAL = &PL_sv_undef;
} else {
# warn("%s, %d\n",result, len);
RETVAL = newSVpvn((char *)result, (STRLEN)len);
xmlFree(result);
}
OUTPUT:
RETVAL
int
is_valid(self, ...)
xmlDocPtr self
PREINIT:
xmlValidCtxt cvp;
ProxyObject * dtd_proxy;
xmlDtdPtr dtd;
SV * dtd_sv;
CODE:
LibXML_error = sv_2mortal(newSVpv("", 0));
cvp.userData = (void*)PerlIO_stderr();
cvp.error = (xmlValidityErrorFunc)LibXML_validity_error;
cvp.warning = (xmlValidityWarningFunc)LibXML_validity_warning;
if (items > 1) {
dtd_sv = ST(1);
if ( sv_isobject(dtd_sv) && (SvTYPE(SvRV(dtd_sv)) == SVt_PVMG) ) {
dtd_proxy = (ProxyObject*)SvIV((SV*)SvRV( dtd_sv ));
if (dtd_proxy != NULL) {
dtd = (xmlDtdPtr)dtd_proxy->object;
}
}
else {
croak("is_valid: argument must be a DTD object");
}
RETVAL = xmlValidateDtd(&cvp, self, dtd);
}
else {
RETVAL = xmlValidateDocument(&cvp, self);
}
OUTPUT:
RETVAL
int
validate(self, ...)
xmlDocPtr self
PREINIT:
xmlValidCtxt cvp;
ProxyObject * dtd_proxy;
xmlDtdPtr dtd;
SV * dtd_sv;
STRLEN n_a;
CODE:
LibXML_error = sv_2mortal(newSVpv("", 0));
cvp.userData = (void*)PerlIO_stderr();
cvp.error = (xmlValidityErrorFunc)LibXML_validity_error;
cvp.warning = (xmlValidityWarningFunc)LibXML_validity_warning;
if (items > 1) {
dtd_sv = ST(1);
if ( sv_isobject(dtd_sv) && (SvTYPE(SvRV(dtd_sv)) == SVt_PVMG) ) {
dtd_proxy = (ProxyObject*)SvIV((SV*)SvRV( dtd_sv ));
if (dtd_proxy != NULL) {
dtd = (xmlDtdPtr)dtd_proxy->object;
}
}
else {
croak("is_valid: argument must be a DTD object");
}
RETVAL = xmlValidateDtd(&cvp, self , dtd);
}
else {
RETVAL = xmlValidateDocument(&cvp, self);
}
if (RETVAL == 0) {
croak(SvPV(LibXML_error, n_a));
}
OUTPUT:
RETVAL
void
process_xinclude(self)
SV* self
PREINIT:
ProxyObject* real_self = (ProxyObject*)SvIV((SV*)SvRV(self));
CODE:
LibXML_init_parser( NULL );
xmlXIncludeProcess((xmlDocPtr)real_self->object);
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
const char *
URI (doc, new_URI=NULL)
xmlDocPtr doc
char * new_URI
CODE:
RETVAL = xmlStrdup(doc->URL );
if (new_URI) {
xmlFree( (xmlChar*) doc->URL);
doc->URL = xmlStrdup((xmlChar*)new_URI);
}
OUTPUT:
RETVAL
SV*
createDocument( CLASS, version="1.0", encoding=0 )
char * CLASS
char * version
char * encoding
ALIAS:
XML::LibXML::Document::new = 1
PREINIT:
xmlDocPtr real_dom=NULL;
ProxyObject * ret= NULL;
CODE:
real_dom = domCreateDocument( version, encoding );
RETVAL = nodeToSv((xmlNodePtr)real_dom);
setSvNodeExtra(RETVAL,RETVAL);
OUTPUT:
RETVAL
SV*
createDocumentFragment( dom )
SV * dom
PREINIT:
SV * frag_sv = NULL;
xmlDocPtr real_dom;
xmlNodePtr fragment= NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
RETVAL = nodeToSv(xmlNewDocFragment( real_dom ));
setSvNodeExtra(RETVAL, RETVAL);
OUTPUT:
RETVAL
SV*
createElement( dom, name )
SV * dom
SV* name
PREINIT:
xmlNodePtr docfrag,newNode;
xmlDocPtr real_dom;
xmlChar * elname = NULL;
SV * docfrag_sv = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
docfrag = xmlNewDocFragment( real_dom );
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv, docfrag_sv);
elname = nodeSv2C( name , (xmlNodePtr) real_dom );
if ( elname != NULL || xmlStrlen(elname) > 0 ) {
newNode = xmlNewNode(NULL , elname);
xmlFree(elname);
if ( newNode != NULL ) {
newNode->doc = real_dom;
domAppendChild( docfrag, newNode );
# warn( newNode->name );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
}
else {
XSRETURN_UNDEF;
}
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
createElementNS( dom, nsURI, qname)
SV * dom
char *nsURI
SV* qname
PREINIT:
xmlNodePtr newNode;
xmlChar *prefix;
xmlChar* quali_name;
xmlChar *lname = NULL;
xmlNsPtr ns = NULL;
xmlDocPtr real_dom;
xmlNodePtr docfrag = NULL;
xmlChar * encstring = NULL;
SV * docfrag_sv = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
quali_name = nodeSv2C( qname , (xmlNodePtr) real_dom );
docfrag = xmlNewDocFragment( real_dom );
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv, docfrag_sv);
if ( nsURI != NULL && strlen(nsURI)!=0 ){
lname = xmlSplitQName2(quali_name, &prefix);
ns = domNewNs (0 , prefix, nsURI );
}
else {
lname = quali_name;
}
newNode = xmlNewNode( ns , lname );
newNode->doc = real_dom;
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
xmlFree(quali_name);
OUTPUT:
RETVAL
SV *
createTextNode( dom, content )
SV * dom
SV * content
PREINIT:
xmlNodePtr newNode;
xmlDocPtr real_dom;
xmlNodePtr docfrag = NULL;
xmlChar * encstring = NULL;
SV * docfrag_sv = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
docfrag = xmlNewDocFragment( real_dom );
docfrag_sv =nodeToSv(docfrag);
encstring = nodeSv2C( content , (xmlNodePtr) real_dom );
newNode = xmlNewDocText( real_dom, encstring );
xmlFree(encstring);
newNode->doc = real_dom;
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
OUTPUT:
RETVAL
SV *
createComment( dom , content )
SV * dom
SV * content
PREINIT:
xmlNodePtr newNode;
xmlDocPtr real_dom;
xmlNodePtr docfrag = NULL;
SV * docfrag_sv = NULL;
char * encstring = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
docfrag = xmlNewDocFragment( real_dom );
docfrag_sv =nodeToSv(docfrag);
encstring = nodeSv2C( content , (xmlNodePtr) real_dom );
newNode = xmlNewDocComment( real_dom, encstring );
xmlFree( encstring );
newNode->doc = real_dom;
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
OUTPUT:
RETVAL
SV *
createCDATASection( dom, content )
SV * dom
SV * content
PREINIT:
xmlNodePtr newNode;
xmlDocPtr real_dom;
xmlNodePtr docfrag = NULL;
SV * docfrag_sv = NULL;
xmlChar * encstring = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
docfrag = xmlNewDocFragment( real_dom );
docfrag_sv =nodeToSv(docfrag);
encstring = nodeSv2C( content , (xmlNodePtr) real_dom );
newNode = domCreateCDATASection( real_dom, encstring );
xmlFree(encstring);
newNode->doc = real_dom;
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
OUTPUT:
RETVAL
SV *
createAttribute( dom, name , value=&PL_sv_undef )
SV * dom
SV * name
SV * value
PREINIT:
xmlNodePtr newNode;
xmlDocPtr real_dom;
xmlChar *encname = NULL;
xmlChar *encval = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
encname = nodeSv2C( name , (xmlNodePtr) real_dom );
encval = nodeSv2C( value , (xmlNodePtr) real_dom );
newNode = (xmlNodePtr)xmlNewProp(NULL, encname , encval );
xmlFree(encname);
xmlFree(encval);
newNode->doc = real_dom;
if ( newNode->children!=NULL ) {
newNode->doc = real_dom;
}
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,dom);
OUTPUT:
RETVAL
SV *
createAttributeNS( dom, nsURI, qname, value=&PL_sv_undef )
SV * dom
char * nsURI
SV * qname
SV * value
PREINIT:
xmlNodePtr newNode;
xmlChar *prefix;
xmlChar *lname =NULL;
xmlChar *encname =NULL;
xmlChar *encval =NULL;
xmlNsPtr ns=NULL;
xmlDocPtr real_dom;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
encname = nodeSv2C( qname , (xmlNodePtr) real_dom );
if ( nsURI != NULL && strlen( nsURI ) != 0 ){
lname = xmlSplitQName2(encname, &prefix);
ns = domNewNs (0 , prefix , (xmlChar*)nsURI);
}
else{
lname = encname;
}
encval = nodeSv2C( value , (xmlNodePtr) real_dom );
if ( ns != NULL ) {
newNode = (xmlNodePtr) xmlNewNsProp(NULL, ns, lname , encval );
}
else {
newNode = (xmlNodePtr) xmlNewProp( NULL, lname, encval );
}
xmlFree(lname);
xmlFree(encname);
xmlFree(encval);
newNode->doc = real_dom;
if ( newNode->children!=NULL ) {
newNode->children->doc = real_dom;
}
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,dom);
OUTPUT:
RETVAL
void
setDocumentElement( dom , proxy )
SV * dom
SV * proxy
PREINIT:
xmlDocPtr real_dom;
xmlNodePtr elem;
SV* oldsv =NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
elem = getSvNode(proxy);
/* please correct me if i am wrong: the document element HAS to be
* an ELEMENT NODE
*/
if ( elem->type == XML_ELEMENT_NODE ) {
domSetDocumentElement( real_dom, elem );
fix_proxy_extra(proxy, dom);
}
SV *
getDocumentElement( dom )
SV * dom
ALIAS:
XML::LibXML::Document::documentElement = 1
PREINIT:
xmlNodePtr elem;
xmlDocPtr real_dom;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
elem = domDocumentElement( real_dom ) ;
if ( elem ) {
RETVAL = nodeToSv(elem);
setSvNodeExtra(RETVAL,dom);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
insertProcessingInstruction( dom, name, content )
SV * dom
SV * name
SV * content
ALIAS:
insertPI = 1
PREINIT:
xmlNodePtr pinode = NULL;
xmlDocPtr real_dom;
xmlChar * enctarg;
xmlChar * encdata;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
enctarg = nodeSv2C( name , (xmlNodePtr) real_dom );
encdata = nodeSv2C( content , (xmlNodePtr) real_dom );
pinode = xmlNewPI( enctarg, encdata );
xmlFree(enctarg);
xmlFree(encdata);
domInsertBefore( (xmlNodePtr)real_dom,
pinode,
domDocumentElement( real_dom ) );
SV *
createProcessingInstruction( dom, name, content=&PL_sv_undef )
SV * dom
SV * name
SV * content
ALIAS:
createPI = 1
PREINIT:
xmlNodePtr newNode;
xmlDocPtr real_dom;
xmlNodePtr docfrag = NULL;
xmlChar * enctarg;
xmlChar * encdata;
SV * docfrag_sv = NULL;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
docfrag = xmlNewDocFragment( real_dom );
docfrag_sv = nodeToSv((xmlNodePtr)docfrag );
enctarg = nodeSv2C( name , (xmlNodePtr) real_dom );
encdata = nodeSv2C( content , (xmlNodePtr) real_dom );
newNode = xmlNewPI( enctarg, encdata );
xmlFree(enctarg);
xmlFree(encdata);
/* newNode = xmlNewPI( name, content ); */
newNode->doc = real_dom;
domAppendChild( docfrag, newNode );
# warn( newNode->name );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
OUTPUT:
RETVAL
SV *
importNode( dom, node, move=0 )
SV * dom
SV * node
int move
PREINIT:
xmlNodePtr ret = NULL;
xmlNodePtr real_node = NULL;
xmlDocPtr real_dom;
CODE:
real_dom = (xmlDocPtr)getSvNode(dom);
real_node= getSvNode(node);
ret = domImportNode( real_dom, real_node, move );
if ( ret ) {
RETVAL = nodeToSv(ret);
if ( move == 0 ){
fix_proxy_extra(RETVAL, dom);
}
else {
setSvNodeExtra(RETVAL, dom);
}
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
char*
getEncoding( self )
SV* self
CODE:
if( self != NULL && self!=&PL_sv_undef) {
RETVAL = xmlStrdup((xmlChar*)((xmlDocPtr)getSvNode(self))->encoding );
}
OUTPUT:
RETVAL
void
setEncoding( self, encoding )
SV* self
char *encoding
CODE:
if( self != NULL && self!=&PL_sv_undef) {
((xmlDocPtr)getSvNode(self))->encoding = xmlStrdup( encoding );
}
char*
getVersion( self )
SV * self
CODE:
if( self != NULL && self != &PL_sv_undef ) {
RETVAL = xmlStrdup( ((xmlDocPtr)getSvNode(self))->version );
}
OUTPUT:
RETVAL
void
setVersion( self, version )
SV* self
char *version
CODE:
if( self != NULL && self!=&PL_sv_undef) {
((xmlDocPtr)getSvNode(self))->version = xmlStrdup( version );
}
MODULE = XML::LibXML PACKAGE = XML::LibXML::Dtd
SV *
new(CLASS, external, system)
char * CLASS
char * external
char * system
CODE:
LibXML_error = sv_2mortal(newSVpv("", 0));
RETVAL = nodeToSv((xmlNodePtr)xmlParseDTD((const xmlChar*)external, (const xmlChar*)system));
OUTPUT:
RETVAL
ProxyObject *
parse_string(CLASS, str, ...)
char * CLASS
char * str
PREINIT:
STRLEN n_a;
xmlDtdPtr res;
SV * encoding_sv;
xmlParserInputBufferPtr buffer;
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
char * new_string;
CODE:
LibXML_error = sv_2mortal(newSVpv("", 0));
if (items > 2) {
encoding_sv = ST(2);
if (items > 3) {
croak("parse_string: too many parameters");
}
/* warn("getting encoding...\n"); */
enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
if (enc == XML_CHAR_ENCODING_ERROR) {
croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
}
}
/* warn("make buffer\n"); */
buffer = xmlAllocParserInputBuffer(enc);
/* xmlParserInputBufferCreateMem(str, strlen(str), enc); */
new_string = xmlStrdup(str);
xmlParserInputBufferPush(buffer, strlen(new_string), new_string);
/* warn("parse\n"); */
res = xmlIOParseDTD(NULL, buffer, enc);
/* warn("free : 0x%x\n", buffer); */
/* NOTE: For some reason freeing this InputBuffer causes a segfault! */
/* xmlFreeParserInputBuffer(buffer); */
/* warn("make proxy\n"); */
if (res != NULL) {
RETVAL = make_proxy_node((xmlNodePtr)res);
}
else {
croak("couldn't parse DTD: %s", SvPV(LibXML_error, n_a));
}
/* warn("return\n"); */
OUTPUT:
RETVAL
void
DESTROY( node )
ProxyObject * node
PREINIT:
xmlDtdPtr real_node;
CODE:
real_node = (xmlDtdPtr)node->object;
if ( node->extra == NULL )
xmlFreeDtd(real_node);
MODULE = XML::LibXML PACKAGE = XML::LibXML::Node
void
DESTROY( node )
SV * node
PREINIT:
SV* dom;
xmlNodePtr real_node;
CODE:
/* XXX should destroy node->extra if refcnt == 0 */
if (node != NULL || node != &PL_sv_undef ) {
real_node = getSvNode(node);
dom = getSvNodeExtra(node);
if ( dom != NULL && dom != &PL_sv_undef && real_node != NULL ) {
if ( SvREFCNT(dom) > 0 ){
SvREFCNT_dec(dom);
}
free_proxy_node(node);
}
}
int
getType( node )
xmlNodePtr node
ALIAS:
XML::LibXML::Node::nodeType = 1
CODE:
RETVAL = node->type;
OUTPUT:
RETVAL
void
unbindNode( proxyelem )
SV* proxyelem
PREINIT:
xmlNodePtr elem = NULL;
xmlNodePtr docfrag = NULL;
ProxyObject * dfProxy = NULL;
SV * docfrag_sv = NULL;
CODE:
elem = getSvNode(proxyelem);
domUnbindNode( elem );
docfrag = xmlNewDocFragment( elem->doc );
docfrag_sv = nodeToSv( docfrag );
setSvNodeExtra( docfrag_sv, docfrag_sv );
domAppendChild( docfrag, elem );
fix_proxy_extra( proxyelem, docfrag_sv );
SV*
removeChild( paren, child )
xmlNodePtr paren
SV* child
PREINIT:
SV* docfrag_sv;
xmlNodePtr ret, docfrag;
CODE:
ret = domRemoveChild( paren, getSvNode(child) );
if (ret != NULL) {
RETVAL = newSVsv(child);
docfrag = xmlNewDocFragment(paren->doc );
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv, docfrag_sv);
fix_proxy_extra(RETVAL,docfrag_sv);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
replaceChild( paren, newChild, oldChild )
SV* paren
SV* newChild
SV* oldChild
PREINIT:
SV* docfrag_sv;
xmlNodePtr pNode, nNode, oNode, docfrag;
xmlNodePtr ret;
CODE:
pNode = getSvNode( paren );
nNode = getSvNode( newChild );
oNode = getSvNode( oldChild );
ret = domReplaceChild( pNode, nNode, oNode );
if (ret != NULL) {
/* create document fragment */
docfrag = xmlNewDocFragment( pNode->doc );
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv, docfrag_sv);
RETVAL = newSVsv(oldChild);
fix_proxy_extra(RETVAL,docfrag_sv);
fix_proxy_extra(newChild,getSvNodeExtra(paren));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
appendChild( parent, child )
SV* parent
SV* child
PREINIT:
ProxyObject* pproxy = NULL;
ProxyObject* cproxy = NULL;
xmlNodePtr test = NULL, pNode, cNode;
CODE:
pNode = getSvNode(parent);
cNode = getSvNode(child);
if ( pNode == NULL ) {
croak("parent problem!\n");
}
if ( cNode == NULL ) {
croak("child problem!\n");
}
if (pNode->type == XML_DOCUMENT_NODE
&& cNode->type == XML_ELEMENT_NODE ) {
/* silently ignore */
xs_warn( "use setDocumentElement!!!!\n" );
}
else {
if ( domAppendChild( pNode, cNode ) != NULL ) {
fix_proxy_extra( child, parent );
}
else {
xs_warn("append problem ...\n");
}
}
SV*
cloneNode( self, deep )
SV* self
int deep
PREINIT:
xmlNodePtr ret;
xmlNodePtr docfrag = NULL;
SV * docfrag_sv = NULL;
xmlNodePtr realself = getSvNode(self);
CODE:
ret = xmlCopyNode( realself, deep );
if (ret != NULL) {
docfrag = xmlNewDocFragment( ret->doc );
docfrag_sv =nodeToSv(docfrag);
domAppendChild( docfrag, ret );
RETVAL = nodeToSv(ret);
fix_proxy_extra(RETVAL, docfrag_sv);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getParentNode( self )
SV* self
ALIAS:
XML::LibXML::Node::parentNode = 1
PREINIT:
xmlNodePtr ret;
CODE:
ret = getSvNode(self)->parent;
if (ret != NULL) {
RETVAL = nodeToSv(ret);
setSvNodeExtra(RETVAL, getSvNodeExtra(self));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
hasChildNodes( elem )
xmlNodePtr elem
CODE:
RETVAL = elem->children == 0 ? 0 : 1 ;
OUTPUT:
RETVAL
SV*
getNextSibling( elem )
SV* elem
ALIAS:
XML::LibXML::Node::nextSibling = 1
PREINIT:
xmlNodePtr ret;
CODE:
ret = getSvNode(elem)->next ;
if ( ret != NULL ) {
RETVAL = nodeToSv(ret);
setSvNodeExtra(RETVAL, getSvNodeExtra(elem));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getPreviousSibling( elem )
SV * elem
ALIAS:
XML::LibXML::Node::previousSibling = 1
PREINIT:
xmlNodePtr ret;
CODE:
ret = getSvNode(elem)->prev;
if ( ret != NULL ) {
RETVAL = nodeToSv(ret);
setSvNodeExtra(RETVAL, getSvNodeExtra(elem));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getFirstChild( elem )
SV* elem
ALIAS:
XML::LibXML::Node::firstChild = 1
PREINIT:
xmlNodePtr ret;
CODE:
ret = getSvNode(elem)->children;
if ( ret != NULL ) {
RETVAL = nodeToSv(ret);
setSvNodeExtra(RETVAL, getSvNodeExtra(elem));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getLastChild( elem )
SV* elem
ALIAS:
XML::LibXML::Node::lastChild = 1
PREINIT:
xmlNodePtr ret;
CODE:
ret = getSvNode(elem)->last;
if ( ret != NULL ) {
RETVAL = nodeToSv(ret);
setSvNodeExtra(RETVAL, getSvNodeExtra(elem));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
insertBefore( self, new, ref )
SV* self
SV* new
SV* ref
PREINIT:
xmlNodePtr pNode, nNode, oNode;
CODE:
pNode = getSvNode(self);
nNode = getSvNode(new);
oNode = getSvNode(ref);
if ( !(pNode->type == XML_DOCUMENT_NODE
&& nNode->type == XML_ELEMENT_NODE )
&& domInsertBefore( pNode, nNode, oNode ) != NULL ) {
fix_proxy_extra(new,getSvNodeExtra(self));
}
void
insertAfter( self, new, ref )
SV* self
SV* new
SV* ref
PREINIT:
xmlNodePtr pNode, nNode, oNode;
CODE:
pNode = getSvNode(self);
nNode = getSvNode(new);
oNode = getSvNode(ref);
if ( !(pNode->type == XML_DOCUMENT_NODE
&& nNode->type == XML_ELEMENT_NODE )
&& domInsertAfter( pNode, nNode, oNode ) != NULL ) {
fix_proxy_extra(new,getSvNodeExtra(self));
}
SV*
getOwnerDocument( elem )
SV* elem
ALIAS:
XML::LibXML::Node::ownerDocument = 1
PREINIT:
xmlNodePtr self = getSvNode(elem);
CODE:
if( self != NULL
&& self->doc != NULL
&& getSvNodeExtra(elem) != NULL ){
RETVAL = getSvNodeExtra(elem);
SvREFCNT_inc( RETVAL );
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getOwner( elem )
SV* elem
CODE:
if( getSvNodeExtra(elem) != NULL ){
RETVAL = getSvNodeExtra(elem);
SvREFCNT_inc( RETVAL );
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
setOwnerDocument( elem, doc )
SV* elem
SV* doc
PREINIT:
xmlDocPtr real_doc;
CODE:
/* no increase here, because owner document is may not the root! */
real_doc = (xmlDocPtr)getSvNode(doc);
domSetOwnerDocument( getSvNode(elem), real_doc );
SV*
getName( node )
xmlNodePtr node
ALIAS:
XML::LibXML::Node::nodeName = 1
XML::LibXML::Attr::name = 2
PREINIT:
char * name;
CODE:
if( node != NULL ) {
name = domName( node );
RETVAL = C2Sv(name,NULL);
xmlFree( name );
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
setName( node , value )
xmlNodePtr node
SV* value
PREINIT:
xmlChar* string;
CODE:
string = nodeSv2C( value , node );
domSetName( node, string );
xmlFree(string);
SV*
getData( proxy_node, useDomEncoding = &PL_sv_undef )
SV * proxy_node
SV * useDomEncoding
ALIAS:
XML::LibXML::Attr::value = 1
XML::LibXML::Node::nodeValue = 2
XML::LibXML::Attr::getValue = 3
PREINIT:
xmlNodePtr node;
xmlChar * content = NULL;
CODE:
/* this implementation is prolly b0rked!
* I have to go through the spec to find out what should
* be returned here.
*/
xs_warn( "getDATA" );
content = domGetNodeValue( getSvNode(proxy_node) );
if ( content != NULL ){
xs_warn ( "content follows"); xs_warn( content );
if ( SvTRUE(useDomEncoding) ) {
RETVAL = nodeC2Sv(content, node);
}
else {
RETVAL = C2Sv(content, NULL);
}
xmlFree(content);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
_findnodes( node, xpath )
SV* node
char * xpath
PREINIT:
xmlNodePtr owner = NULL;
xmlNodeSetPtr nodelist = NULL;
SV * element = NULL ;
int len = 0 ;
PPCODE:
nodelist = domXPathSelect( getSvNode(node), xpath );
if ( nodelist && nodelist->nodeNr > 0 ) {
int i = 0 ;
const char * cls = "XML::LibXML::Node";
xmlNodePtr tnode;
owner = getSvNode(getSvNodeExtra(node));
len = nodelist->nodeNr;
for( i ; i < len; i++){
/* we have to create a new instance of an objectptr. and then
* place the current node into the new object. afterwards we can
* push the object to the array!
*/
element = NULL;
tnode = nodelist->nodeTab[i];
if (tnode->type == XML_NAMESPACE_DECL) {
element = sv_newmortal();
cls = domNodeTypeName( tnode );
element = sv_setref_pv( element, (char *)cls, (void*)tnode );
}
else {
if ( tnode == owner ) {
element = getSvNodeExtra(node);
}
else {
element = nodeToSv(tnode);
}
setSvNodeExtra(element, getSvNodeExtra(node));
}
XPUSHs( element );
}
xmlXPathFreeNodeSet( nodelist );
}
void
_find ( node, xpath )
SV* node
char * xpath
PREINIT:
xmlNodePtr owner = NULL;
xmlXPathObjectPtr found = NULL;
xmlNodeSetPtr nodelist = NULL;
SV* element = NULL ;
int len = 0 ;
PPCODE:
found = domXPathFind( getSvNode(node), xpath );
if (found) {
switch (found->type) {
case XPATH_NODESET:
/* return as a NodeList */
/* access ->nodesetval */
XPUSHs(newSVpv("XML::LibXML::NodeList", 0));
nodelist = found->nodesetval;
if ( nodelist && nodelist->nodeNr > 0 ) {
int i = 0 ;
const char * cls = "XML::LibXML::Node";
xmlNodePtr tnode;
SV * element;
owner = getSvNode(getSvNodeExtra(node));
len = nodelist->nodeNr;
for( i ; i < len; i++){
/* we have to create a new instance of an
* objectptr. and then
* place the current node into the new
* object. afterwards we can
* push the object to the array!
*/
tnode = nodelist->nodeTab[i];
if ( tnode == owner ) {
element = getSvNodeExtra(node);
}
else {
element = nodeToSv(tnode);
}
setSvNodeExtra(element,getSvNodeExtra(node));
XPUSHs( element );
}
}
break;
case XPATH_BOOLEAN:
/* return as a Boolean */
/* access ->boolval */
XPUSHs(newSVpv("XML::LibXML::Boolean", 0));
XPUSHs(newSViv(found->boolval));
break;
case XPATH_NUMBER:
/* return as a Number */
/* access ->floatval */
XPUSHs(newSVpv("XML::LibXML::Number", 0));
XPUSHs(newSVnv(found->floatval));
break;
case XPATH_STRING:
/* access ->stringval */
/* return as a Literal */
XPUSHs(newSVpv("XML::LibXML::Literal", 0));
XPUSHs(newSVpv(found->stringval, 0));
break;
default:
croak("Unknown XPath return type");
}
xmlXPathFreeObject(found);
}
void
getChildnodes( node )
SV* node
ALIAS:
XML::LibXML::Node::childNodes = 1
PREINIT:
xmlNodePtr cld;
SV * element;
int len = 0;
int wantarray = GIMME_V;
PPCODE:
cld = getSvNode(node)->children;
xs_warn("childnodes start");
while ( cld ) {
if( wantarray != G_SCALAR ) {
xs_warn(" --");
xs_warn(domNodeTypeName(cld));
element = nodeToSv(cld);
if( cld->type == XML_PI_NODE ) {
xs_warn("pi found!!!!");
}
setSvNodeExtra(element, getSvNodeExtra(node));
xs_warn(" +-");
XPUSHs( element );
}
xs_warn(" -+");
cld = cld->next;
len++;
}
xs_warn("childnodes start");
if ( wantarray == G_SCALAR ) {
XPUSHs( newSViv(len) );
}
SV*
toString( self, useDomEncoding = &PL_sv_undef )
xmlNodePtr self
SV * useDomEncoding
PREINIT:
xmlBufferPtr buffer;
char *ret = NULL;
CODE:
buffer = xmlBufferCreate();
xmlNodeDump( buffer, self->doc, self, 0, 0 );
if ( buffer->content != 0 ) {
ret= xmlStrdup( buffer->content );
}
xmlBufferFree( buffer );
if ( ret != NULL ) {
if ( SvTRUE(useDomEncoding) ) {
RETVAL = nodeC2Sv(ret, self) ;
}
else {
RETVAL = C2Sv(ret, NULL) ;
}
xmlFree( ret );
}
else {
# warn("Failed to convert doc to string");
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
isEqual( self, other )
xmlNodePtr self
xmlNodePtr other
ALIAS:
XML::LibXML::Node::isSameNode = 1
CODE:
RETVAL = 0;
if( self == other ) {
RETVAL = 1;
}
OUTPUT:
RETVAL
int
getPointer( self )
xmlNodePtr self
CODE:
RETVAL = (int)self;
OUTPUT:
RETVAL
SV*
getLocalName( node )
xmlNodePtr node
ALIAS:
XML::LibXML::Node::localname = 1
PREINIT:
char * lname;
CODE:
if( node != NULL ) {
lname = xmlStrdup( node->name );
RETVAL = C2Sv(lname,NULL);
xmlFree( lname );
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getPrefix( node )
xmlNodePtr node
ALIAS:
XML::LibXML::Node::prefix = 1
PREINIT:
xmlChar * prefix;
CODE:
if( node != NULL
&& node->ns != NULL
&& node->ns->prefix != NULL ) {
prefix = xmlStrdup(node->ns->prefix);
RETVAL = C2Sv(prefix, NULL);
xmlFree(prefix);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getNamespaceURI( node )
xmlNodePtr node
PREINIT:
xmlChar * nsURI;
CODE:
if( node != NULL
&& node->ns != NULL
&& node->ns->href != NULL ) {
nsURI = xmlStrdup(node->ns->href);
RETVAL = C2Sv(nsURI,NULL);
xmlFree(nsURI);
}
else {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
int
hasAttributes( node )
SV* node
PREINIT:
xmlNodePtr self = getSvNode(node);
CODE:
RETVAL = 0;
if( self->type == 1
||self->type == 7
||self->type >= 9 ) {
if( self->properties != NULL ) {
RETVAL = 1;
}
}
OUTPUT:
RETVAL
void
getAttributes( node )
SV* node
ALIAS:
XML::LibXML::Node::attributes = 1
PREINIT:
xmlAttrPtr attr = NULL;
xmlNodePtr real_node = NULL;
xmlNsPtr ns = NULL;
SV * element;
int len=0;
const char * CLASS = "XML::LibXML::Attr";
int wantarray = GIMME_V;
PPCODE:
real_node = getSvNode(node);
attr = real_node->properties;
while ( attr != NULL ) {
if ( wantarray != G_SCALAR ) {
element = nodeToSv((xmlNodePtr)attr);
setSvNodeExtra(element,getSvNodeExtra(node));
XPUSHs(element);
}
attr = attr->next;
len++;
}
ns = real_node->nsDef;
while ( ns != NULL ) {
const char * CLASS = "XML::LibXML::Namespace";
if ( wantarray != G_SCALAR ) {
/* hmm this namespace handling looks odd ... */
element = sv_newmortal();
XPUSHs( sv_setref_pv( element, (char *)CLASS, (void*)ns ) );
}
ns = ns->next;
len++;
}
if( wantarray == G_SCALAR ) {
XPUSHs( newSViv( len ) );
}
void
getAttributesNS( node,nsURI )
SV* node
char * nsURI
PREINIT:
xmlAttrPtr attr = NULL;
xmlNodePtr real_node = NULL;
SV * element;
int len = 0;
const char * CLASS = "XML::LibXML::Attr";
int wantarray = GIMME_V;
PPCODE:
real_node = (xmlNodePtr)getSvNode(node);
attr = real_node->properties;
while ( attr != NULL ) {
if( attr->ns != NULL && xmlStrcmp( nsURI, attr->ns->href ) == 0 ){
if( wantarray != G_SCALAR ) {
element = nodeToSv((xmlNodePtr)attr);
setSvNodeExtra(element,getSvNodeExtra(node));
XPUSHs( element );
}
len++;
}
attr = attr->next;
}
if( wantarray == G_SCALAR ) {
XPUSHs( newSViv( len ) );
}
void
getNamespaces ( node )
xmlNodePtr node
ALIAS:
XML::LibXML::Node::namespaces = 1
PREINIT:
xmlNsPtr ns = NULL;
int len=0;
const char * CLASS = "XML::LibXML::Namespace";
int wantarray = GIMME_V;
SV * element;
PPCODE:
ns = node->nsDef;
while ( ns != NULL ) {
if ( wantarray != G_SCALAR ) {
element = sv_newmortal();
XPUSHs( sv_setref_pv( element, (char *)CLASS, (void*)ns ) );
}
ns = ns->next;
len++;
}
if( wantarray == G_SCALAR ) {
XPUSHs( newSViv( len ) );
}
void
getNamespace ( node, perlprefix )
xmlNodePtr node
SV * perlprefix
PREINIT:
xmlDocPtr real_dom= NULL;
xmlChar *prefix;
xmlNsPtr ns = NULL;
const char * CLASS = "XML::LibXML::Namespace";
SV * element;
PPCODE:
if ( node != NULL && perlprefix != NULL && perlprefix != &PL_sv_undef ) {
prefix = nodeSv2C( perlprefix, node );
ns = node->nsDef;
while ( ns != NULL ) {
if (ns->prefix != NULL) {
if (xmlStrcmp(prefix, ns->prefix) == 0) {
element = sv_newmortal();
XPUSHs( sv_setref_pv( element, (char *)CLASS, (void*)ns ) );
break;
}
} else {
if (xmlStrlen(prefix) == 0) {
element = sv_newmortal();
XPUSHs( sv_setref_pv( element, (char *)CLASS, (void*)ns ) );
break;
}
}
ns = ns->next;
}
xmlFree(prefix);
}
SV*
string_value ( node, useDomEncoding = &PL_sv_undef )
xmlNodePtr node
SV * useDomEncoding
ALIAS:
to_literal = 1
CODE:
/* we can't just return a string, because of UTF8! */
if ( SvTRUE(useDomEncoding) ) {
RETVAL = nodeC2Sv(xmlXPathCastNodeToString(node), node);
}
else {
RETVAL = C2Sv(xmlXPathCastNodeToString(node), NULL);
}
OUTPUT:
RETVAL
double
to_number ( node )
xmlNodePtr node
CODE:
RETVAL = xmlXPathCastNodeToNumber(node);
OUTPUT:
RETVAL
MODULE = XML::LibXML PACKAGE = XML::LibXML::Element
SV*
new(CLASS, name )
char * CLASS
char * name
PREINIT:
xmlNodePtr newNode;
CODE:
newNode = xmlNewNode( 0, name );
if( newNode != NULL ) {
# init the keeping fragment
xmlNodePtr docfrag = NULL;
ProxyObject * dfProxy = NULL;
SV * docfrag_sv = NULL;
docfrag = xmlNewDocFragment(NULL);
docfrag_sv= nodeToSv(docfrag);
newNode->next = 0;
newNode->prev = 0;
newNode->children = 0 ;
newNode->last = 0;
newNode->doc = 0;
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
fix_proxy_extra(RETVAL, docfrag_sv);
}
OUTPUT:
RETVAL
void
setAttribute( perlelem, name, value )
SV* perlelem
SV* name
SV* value
PREINIT:
xmlNodePtr elem;
xmlChar* xname;
xmlChar* xvalue;
CODE:
if ( elem = getSvNode(perlelem) ) {
xname = nodeSv2C( name , elem );
xvalue = nodeSv2C( value , elem );
xmlSetProp( elem, xname, xvalue );
xmlFree( xname );
xmlFree( xvalue );
}
void
setAttributeNS( elem, nsURI, qname, value )
xmlNodePtr elem
char* nsURI
SV* qname
SV* value
PREINIT:
xmlDocPtr real_dom;
xmlChar *xqname;
xmlChar *xvalue;
xmlChar *prefix = NULL;
xmlChar *lname = NULL;
xmlNsPtr ns = NULL;
CODE:
xqname = nodeSv2C( qname , elem );
xvalue = nodeSv2C( value , elem );
if ( nsURI != NULL && xmlStrlen(nsURI) != 0 ) {
lname = xmlSplitQName2(xqname, &prefix);
ns = domNewNs (elem , prefix , nsURI);
xmlSetNsProp( elem, ns, lname, xvalue );
xmlFree(lname);
xmlFree(prefix);
}
else {
xmlSetProp( elem, xqname, xvalue );
}
xmlFree( xqname );
xmlFree( xvalue );
SV *
setAttributeNode( elem, attrnode )
SV * elem
SV * attrnode
CODE:
/* this chunk is not 100% correct, sind the SV already exists.
* the future version of nodeToSv should get the correct value!
*/
if ( elem != NULL
&& elem != &PL_sv_undef
&& attrnode != NULL
&& attrnode != &PL_sv_undef ) {
RETVAL = nodeToSv( (xmlNodePtr)domSetAttributeNode( getSvNode(elem), (xmlAttrPtr)getSvNode(attrnode) ) );
setSvNodeExtra(RETVAL, getSvNodeExtra(elem));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
hasAttribute( elem, pname )
xmlNodePtr elem
SV * pname
PREINIT:
xmlAttrPtr att = NULL;
xmlChar *name = NULL;
xmlDocPtr real_dom = NULL;
CODE:
if ( elem != NULL && pname != NULL && pname!=&PL_sv_undef ){
name = nodeSv2C( pname , elem );
/**
* xmlHasProp() returns the attribute node, which is not
* exactly what we want as a boolean value
**/
att = xmlHasProp( elem, name );
xmlFree( name );
RETVAL = att == NULL ? 0 : 1 ;
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
hasAttributeNS( elem, nsURI, pname )
xmlNodePtr elem
char * nsURI
SV * pname
PREINIT:
xmlChar *name = NULL;
xmlDocPtr real_dom = NULL;
xmlAttrPtr att = NULL;
CODE:
if ( elem != NULL && pname != NULL && pname!=&PL_sv_undef ){
name = nodeSv2C( pname , elem );
/**
* domHasNsProp() returns the attribute node, which is not
* exactly what
* we want as a boolean value
**/
att = domHasNsProp( elem, name, nsURI );
xmlFree(name);
RETVAL = att == NULL ? 0 : 1 ;
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getAttribute( elem, pname )
SV * elem
SV * pname
PREINIT:
xmlNodePtr node;
xmlChar * name;
xmlChar * content = NULL;
CODE:
node = getSvNode( elem );
name = nodeSv2C( pname, node );
content = xmlGetProp( node , name );
if ( content != NULL ) {
RETVAL = C2Sv(content, NULL );
xmlFree( content );
}
else {
XSRETURN_UNDEF;
}
xmlFree(name);
OUTPUT:
RETVAL
SV*
getAttributeNS( elem, nsURI ,pname )
SV* elem
char * nsURI
SV * pname
PREINIT:
xmlAttrPtr att;
xmlNodePtr node;
xmlChar * name;
xmlChar * content = NULL;
CODE:
node = getSvNode( elem );
name = nodeSv2C( pname, node );
att = domHasNsProp( node, name, nsURI );
if ( att != NULL && att->children != NULL ) {
content = xmlStrdup( att->children->content );
}
if ( content != NULL ) {
RETVAL = C2Sv(content,NULL);
xmlFree( content );
}
else {
XSRETURN_UNDEF;
}
xmlFree( name );
OUTPUT:
RETVAL
SV *
getAttributeNode( elemnode, pname )
SV * elemnode
SV * pname
PREINIT:
xmlChar* name;
xmlDocPtr real_dom = NULL;
xmlNodePtr elem;
xmlAttrPtr attrnode = NULL;
CODE:
elem = getSvNode(elemnode);
if ( elem != NULL ) {
name = nodeSv2C( pname , elem );
attrnode = xmlHasProp( elem, name );
if ( attrnode != NULL ) {
RETVAL = nodeToSv((xmlNodePtr)attrnode);
setSvNodeExtra(RETVAL,getSvNodeExtra(elemnode));
}
else {
XSRETURN_UNDEF;
}
xmlFree(name);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV *
getAttributeNodeNS( elemobj, nsURI, pname )
SV* elemobj
char * nsURI
SV * pname
PREINIT:
xmlChar* name;
xmlDocPtr real_dom = NULL;
xmlNodePtr elem;
xmlAttrPtr attrnode = NULL;
CODE:
elem = getSvNode(elemobj);
if ( elem != NULL ) {
name = nodeSv2C( pname ,elem );
attrnode = domHasNsProp( elem, name, nsURI );
if ( attrnode != NULL ) {
RETVAL = nodeToSv((xmlNodePtr)attrnode);
setSvNodeExtra(RETVAL,getSvNodeExtra(elemobj));
}
else {
XSRETURN_UNDEF;
}
xmlFree(name);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
removeAttribute( elem, pname )
xmlNodePtr elem
SV * pname
PREINIT:
xmlChar *name = NULL;
xmlDocPtr real_dom = NULL;
CODE:
if ( elem != NULL && pname != NULL && pname!=&PL_sv_undef ){
name = nodeSv2C( pname , elem );
xmlRemoveProp( xmlHasProp( elem, name ) );
xmlFree(name);
}
void
removeAttributeNS( elem, nsURI, pname )
xmlNodePtr elem
char * nsURI
SV * pname
PREINIT:
xmlChar *prefix;
xmlChar *lname = NULL;
xmlNsPtr ns = NULL;
xmlChar *name = NULL;
xmlDocPtr real_dom = NULL;
CODE:
if ( elem != NULL && pname != NULL && pname!=&PL_sv_undef ){
name = nodeSv2C( pname , elem );
if ( nsURI != NULL ) {
lname = xmlSplitQName2(name, &prefix);
if (lname == NULL) /* as it is supposed to be */
lname = name;
/* ignore the given prefix if any, and use whatever
is defined in scope for this nsURI */
ns = xmlSearchNsByHref(elem->doc, elem, nsURI);
xmlUnsetNsProp( elem, ns, lname );
}
else {
xmlRemoveProp( xmlHasProp( elem, name ) );
}
xmlFree( name );
}
void
getChildrenByTagName( elem, pname )
SV* elem
SV * pname
PREINIT:
xmlNodePtr node;
xmlNodeSetPtr nodelist;
SV * element;
int len = 0;
int wantarray = GIMME_V;
xmlChar * name;
PPCODE:
node = getSvNode(elem);
name = nodeSv2C( pname , node );
nodelist = domGetElementsByTagName( node , name );
xmlFree(name);
if ( nodelist && nodelist->nodeNr > 0 ) {
int i = 0 ;
xmlNodePtr tnode;
len = nodelist->nodeNr;
if( wantarray == G_ARRAY ) {
for( i ; i < len; i++){
/* we have to create a new instance of an objectptr. and then
* place the current node into the new object. afterwards we can
* push the object to the array!
*/
element = NULL;
tnode = nodelist->nodeTab[i];
element = nodeToSv(tnode);
if ( getSvNodeExtra != NULL ) {
setSvNodeExtra(element, getSvNodeExtra(elem));
}
XPUSHs( element );
}
}
else {
XPUSHs( newSViv( len ) );
}
xmlXPathFreeNodeSet( nodelist );
}
void
getChildrenByTagNameNS( elem, nsURI, pname )
SV* elem
char * nsURI
SV * pname
PREINIT:
xmlNodePtr node;
xmlNodeSetPtr nodelist;
xmlChar * name;
SV * element;
int len = 0;
int wantarray = GIMME_V;
PPCODE:
node = getSvNode(elem);
name = nodeSv2C(pname,node);
nodelist = domGetElementsByTagNameNS( node , nsURI , name );
xmlFree(name);
if ( nodelist && nodelist->nodeNr > 0 ) {
int i = 0 ;
xmlNodePtr tnode;
len = nodelist->nodeNr;
if( wantarray == G_ARRAY ) {
for( i ; i < len; i++){
/* we have to create a new instance of an objectptr. and then
* place the current node into the new object. afterwards we can
* push the object to the array!
*/
element = NULL;
tnode = nodelist->nodeTab[i];
element = nodeToSv(tnode);
if ( getSvNodeExtra(elem) != NULL ) {
setSvNodeExtra(element, getSvNodeExtra(elem));
}
XPUSHs( element );
}
}
else {
XPUSHs( newSViv( len ) );
}
xmlXPathFreeNodeSet( nodelist );
}
void
appendWellBalancedChunk( self, chunk )
xmlNodePtr self
SV * chunk
PREINIT:
xmlChar * encvalue;
xmlNodePtr rv;
xmlDocPtr real_dom = NULL;
CODE:
if ( self != NULL
&& chunk != NULL
&& chunk != &PL_sv_undef ) {
encvalue = nodeSv2C(chunk, self);
LibXML_error = sv_2mortal(newSVpv("", 0));
rv = domReadWellBalancedString( self->doc, encvalue );
LibXML_cleanup_callbacks();
LibXML_cleanup_parser();
if ( rv != NULL ) {
xmlAddChildList( self , rv );
}
if( encvalue != NULL )
xmlFree( encvalue );
}
void
appendTextNode( self, xmlString )
xmlNodePtr self
SV * xmlString
ALIAS:
XML::LibXML::Element::appendText = 1
PREINIT:
xmlDocPtr real_dom= NULL;
xmlChar * encvalue = NULL;
CODE:
if ( self != NULL
&& xmlString != NULL
&& xmlString != &PL_sv_undef ) {
encvalue = nodeSv2C(xmlString, self);
domAppendChild( self, xmlNewText( encvalue ) );
xmlFree(encvalue);
}
void
appendTextChild( self, childname, xmlString )
xmlNodePtr self
SV * childname
SV * xmlString
PREINIT:
xmlChar * encname = NULL;
xmlChar * enccontent= NULL;
xmlDocPtr real_dom = NULL;
CODE:
if ( self != NULL ) {
enccontent = nodeSv2C(xmlString, self);
encname = nodeSv2C(childname, self);
xmlNewTextChild( self, NULL, encname, enccontent );
xmlFree(encname);
xmlFree(enccontent);
}
MODULE = XML::LibXML PACKAGE = XML::LibXML::PI
void
_setData( node, value )
xmlNodePtr node
SV * value
PREINIT:
xmlDocPtr real_dom = NULL;
xmlChar * encstr;
CODE:
if ( node != NULL ) {
encstr = nodeSv2C(value,node);
domSetNodeValue( node, encstr );
xmlFree( encstr );
}
MODULE = XML::LibXML PACKAGE = XML::LibXML::Text
SV *
substringData( node, offset, length )
xmlNodePtr node
int offset
int length
PREINIT:
xmlChar * data = NULL;
xmlChar * substr = NULL;
int len = 0;
int dl = 0;
CODE:
if ( node != NULL && offset >= 0 && length > 0 ) {
dl = offset + length - 1 ;
data = domGetNodeValue( node );
len = xmlStrlen( data );
if ( data != NULL && len > 0 && len > offset ) {
if ( dl > len )
dl = offset + len;
substr = xmlStrsub( data, offset, dl );
RETVAL = C2Sv( (const xmlChar*)substr, NULL );
xmlFree( substr );
}
else {
XSRETURN_UNDEF;
}
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
setData( node, value )
xmlNodePtr node
SV * value
ALIAS:
XML::LibXML::Attr::setValue = 1
# XML::LibXML::PI::_setData = 2
PREINIT:
xmlChar * encstr = NULL;
CODE:
if ( node != NULL ) {
encstr = nodeSv2C(value,node);
domSetNodeValue( node, encstr );
xmlFree(encstr);
}
void
appendData( node, value )
xmlNodePtr node
SV * value
PREINIT:
xmlChar * data = NULL;
xmlChar * encstring = NULL;
CODE:
if ( node != NULL ) {
encstring = Sv2C( value,
node->doc!=NULL ? node->doc->encoding : NULL );
if ( encstring != NULL && xmlStrlen( encstring ) > 0 ) {
data = domGetNodeValue( node );
if ( data != NULL && xmlStrlen( data ) > 0) {
data = xmlStrcat( data, encstring );
domSetNodeValue( node, data );
xmlFree( encstring );
xmlFree( data );
}
else {
domSetNodeValue( node, encstring );
xmlFree( encstring );
}
}
}
void
insertData( node, offset, value )
xmlNodePtr node
int offset
SV * value
PREINIT:
xmlChar * after= NULL;
xmlChar * data = NULL;
xmlChar * new = NULL;
xmlChar * encstring = NULL;
int dl = 0;
CODE:
if ( node != NULL && offset >= 0 ) {
encstring = Sv2C( value,
node->doc!=NULL ? node->doc->encoding : NULL );
if ( encstring != NULL && xmlStrlen( encstring ) > 0 ) {
data = domGetNodeValue(node);
if ( data != NULL && xmlStrlen( data ) > 0 ) {
if ( xmlStrlen( data ) < offset ) {
data = xmlStrcat( data, encstring );
domSetNodeValue( node, data );
}
else {
dl = xmlStrlen( data ) - offset;
if ( offset > 0 )
new = xmlStrsub(data, 0, offset );
after = xmlStrsub(data, offset, dl );
if ( new != NULL ) {
new = xmlStrcat(new, encstring );
}
else {
new = xmlStrdup( encstring );
}
if ( after != NULL )
new = xmlStrcat(new, after );
domSetNodeValue( node, new );
xmlFree( new );
xmlFree( after );
}
xmlFree( data );
}
else {
domSetNodeValue( node, encstring );
}
xmlFree(encstring);
}
}
void
deleteData( node, offset, length )
xmlNodePtr node
int offset
int length
PREINIT:
xmlChar * data = NULL;
xmlChar * after = NULL;
xmlChar * new = NULL;
int len = 0;
int dl1 = 0;
int dl2 = 0;
CODE:
if ( node != NULL && length > 0 && offset >= 0 ) {
data = domGetNodeValue(node);
len = xmlStrlen( data );
if ( data != NULL
&& len > 0
&& len > offset ) {
dl1 = offset + length;
if ( offset > 0 )
new = xmlStrsub( data, 0, offset );
if ( len > dl1 ) {
dl2 = len - dl1;
after = xmlStrsub( data, dl1, dl2 );
if ( new != NULL ) {
new = xmlStrcat( new, after );
xmlFree(after);
}
else {
new = after;
}
}
domSetNodeValue( node, new );
xmlFree(new);
}
}
void
replaceData( node, offset,length, value )
xmlNodePtr node
int offset
int length
SV * value
PREINIT:
xmlChar * after= NULL;
xmlChar * data = NULL;
xmlChar * new = NULL;
xmlChar * encstring = NULL;
int len = 0;
int dl1 = 0;
int dl2 = 0;
CODE:
if ( node != NULL && offset >= 0 ) {
encstring = Sv2C( value,
node->doc!=NULL ? node->doc->encoding : NULL );
if ( encstring != NULL && xmlStrlen( encstring ) > 0 ) {
data = domGetNodeValue(node);
len = xmlStrlen( data );
if ( data != NULL
&& len > 0
&& len > offset ) {
dl1 = offset + length;
if ( dl1 < len ) {
dl2 = xmlStrlen( data ) - dl1;
if ( offset > 0 ) {
new = xmlStrsub(data, 0, offset );
new = xmlStrcat(new, encstring );
}
else {
new = xmlStrdup( encstring );
}
after = xmlStrsub(data, dl1, dl2 );
new = xmlStrcat(new, after );
domSetNodeValue( node, new );
xmlFree( new );
xmlFree( after );
}
else {
/* replace until end! */
if ( offset > 0 ) {
new = xmlStrsub(data, 0, offset );
new = xmlStrcat(new, encstring );
}
else {
new = xmlStrdup( encstring );
}
domSetNodeValue( node, new );
xmlFree( new );
}
xmlFree( data );
}
xmlFree(encstring);
}
}
SV *
new( CLASS, content )
const char * CLASS
SV * content
PREINIT:
xmlChar * data;
xmlNodePtr newNode;
CODE:
/* we should test if this is UTF8 ... because this WILL cause
* problems with iso encoded strings :(
*/
data = Sv2C(content, NULL);
newNode = xmlNewText( data );
xmlFree(data);
if( newNode != NULL ) {
# init the keeping fragment
xmlNodePtr docfrag = NULL;
SV * docfrag_sv = NULL;
docfrag = xmlNewDocFragment(NULL);
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv,docfrag_sv);
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
MODULE = XML::LibXML PACKAGE = XML::LibXML::Comment
SV *
new( CLASS, content )
const char * CLASS
SV * content
PREINIT:
xmlChar * encstring;
xmlNodePtr newNode;
CODE:
encstring = Sv2C(content, NULL);
newNode = xmlNewComment( encstring );
xmlFree(encstring);
if( newNode != NULL ) {
xmlNodePtr docfrag = NULL;
SV * docfrag_sv = NULL;
docfrag = xmlNewDocFragment(NULL);
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv,docfrag_sv);
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
MODULE = XML::LibXML PACKAGE = XML::LibXML::CDATASection
SV *
new( CLASS , content )
const char * CLASS
SV * content
PREINIT:
xmlChar * encstring;
xmlNodePtr newNode;
CODE:
encstring = Sv2C(content, NULL);
newNode = xmlNewCDataBlock( 0 , encstring, xmlStrlen( encstring ) );
xmlFree(encstring);
if ( newNode != NULL ){
# init the keeping fragment
xmlNodePtr docfrag = NULL;
SV * docfrag_sv = NULL;
docfrag = xmlNewDocFragment(NULL);
docfrag_sv = nodeToSv(docfrag);
setSvNodeExtra(docfrag_sv,docfrag_sv);
domAppendChild( docfrag, newNode );
RETVAL = nodeToSv(newNode);
setSvNodeExtra(RETVAL,docfrag_sv);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
MODULE = XML::LibXML PACKAGE = XML::LibXML::Attr
SV *
new( CLASS , name="", value="" )
char * CLASS
char * name
char * value
PREINIT:
xmlNodePtr attr = NULL;
CODE:
attr = (xmlNodePtr)xmlNewProp( NULL, name, value );
attr->doc = NULL;
RETVAL = nodeToSv(attr);
OUTPUT:
RETVAL
void
DESTROY(self)
SV * self
CODE:
if (self != NULL || self != &PL_sv_undef ) {
xmlNodePtr object = getSvNode(self);
if ( object != NULL
&& object->parent == NULL ) {
object->doc = NULL;
xmlFreeProp((xmlAttrPtr)object);
# warn( "REAL ATTRIBUTE DROPPED" );
}
free_proxy_node(self);
}
else {
XSRETURN_UNDEF;
}
SV *
getOwnerElement( attrnode )
SV * attrnode
ALIAS:
XML::LibXML::Attr::ownerElement = 1
PREINIT:
const char * CLASS = "XML::LibXML::Node";
xmlNodePtr attr;
xmlNodePtr parent;
CODE:
attr = (xmlNodePtr)getSvNode(attrnode);
parent = attr->parent;
if ( parent != NULL ) {
RETVAL = nodeToSv(parent);
setSvNodeExtra(RETVAL,getSvNodeExtra(attrnode));
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
getParentElement( attrnode )
ProxyObject * attrnode
ALIAS:
XML::LibXML::Attr::parentNode = 1
CODE:
XSRETURN_UNDEF;
OUTPUT:
RETVAL
MODULE = XML::LibXML PACKAGE = XML::LibXML::DocumentFragment
SV*
new( CLASS )
char * CLASS
PREINIT:
SV * frag_sv = NULL;
xmlNodePtr real_dom=NULL;
CODE:
real_dom = xmlNewDocFragment( NULL );
RETVAL = nodeToSv( real_dom );
setSvNodeExtra(RETVAL,RETVAL);
OUTPUT:
RETVAL
void
DESTROY(self)
SV* self
PREINIT:
xmlNodePtr object;
CODE:
if (self != NULL || self != &PL_sv_undef ) {
xs_warn("destroy fragment");
/* check if the refcnt is 0 or 1 */
object = getSvNode(self);
if ( object != NULL ) {
xmlFreeNode(object);
}
free_proxy_node(self);
}
MODULE = XML::LibXML PACKAGE = XML::LibXML::Namespace
SV *
getName (self)
xmlNsPtr self
ALIAS:
XML::LibXML::Namespace::name = 1
CODE:
if (self->prefix != NULL && strlen(self->prefix) > 0) {
RETVAL = newSVpv("xmlns:", 0);
sv_catpv(RETVAL, (char*)self->prefix);
} else {
RETVAL = newSVpv("xmlns", 0);
}
OUTPUT:
RETVAL
SV *
prefix (self)
xmlNsPtr self
ALIAS:
XML::LibXML::Namespace::getLocalName = 1
XML::LibXML::Namespace::localName = 2
CODE:
RETVAL = C2Sv(self->prefix, NULL);
OUTPUT:
RETVAL
SV *
getData (self)
xmlNsPtr self
ALIAS:
XML::LibXML::Namespace::value = 1
XML::LibXML::Namespace::getValue = 2
XML::LibXML::Namespace::uri = 3
CODE:
RETVAL = C2Sv(self->href, NULL);
OUTPUT:
RETVAL
char *
getNamespaceURI (self)
xmlNsPtr self
CODE:
RETVAL = "http://www.w3.org/2000/xmlns/";
OUTPUT:
RETVAL
char *
getPrefix (self)
xmlNsPtr self
CODE:
RETVAL = "xmlns";
OUTPUT:
RETVAL
int
getPointer( self )
xmlNsPtr self
CODE:
RETVAL = (int)self;
OUTPUT:
RETVAL