1/* $Id: LibXML.xs,v 1.1.1.2 2007/10/10 23:04:13 ahuda Exp $ */ 2 3#ifdef __cplusplus 4extern "C" { 5#endif 6 7/* perl stuff */ 8#include "EXTERN.h" 9#include "perl.h" 10#include "XSUB.h" 11#include "ppport.h" 12#include "Av_CharPtrPtr.h" /* XS_*_charPtrPtr() */ 13 14#include <fcntl.h> 15 16#ifndef WIN32 17# include <unistd.h> 18#endif 19 20/* libxml2 configuration properties */ 21#include <libxml/xmlversion.h> 22 23#define DEBUG_C14N 24 25/* libxml2 stuff */ 26#include <libxml/xmlversion.h> 27#include <libxml/globals.h> 28#include <libxml/xmlmemory.h> 29#include <libxml/parser.h> 30#include <libxml/parserInternals.h> 31#include <libxml/HTMLparser.h> 32#include <libxml/HTMLtree.h> 33#include <libxml/c14n.h> 34#include <libxml/tree.h> 35#include <libxml/xpath.h> 36#include <libxml/xpathInternals.h> 37#include <libxml/xmlIO.h> 38/* #include <libxml/debugXML.h> */ 39#include <libxml/xmlerror.h> 40#include <libxml/xinclude.h> 41#include <libxml/valid.h> 42 43#if LIBXML_VERSION >= 20510 44#define HAVE_SCHEMAS 45#include <libxml/relaxng.h> 46#include <libxml/xmlschemas.h> 47#endif 48 49#if LIBXML_VERSION >= 20621 50#define HAVE_READER_SUPPORT 51#include <libxml/xmlreader.h> 52#endif 53 54#ifdef LIBXML_CATALOG_ENABLED 55#include <libxml/catalog.h> 56#endif 57 58/* GDOME support 59 * libgdome installs only the core functions to the system. 60 * this is not enough for XML::LibXML <-> XML::GDOME conversion. 61 * therefore there is the need to ship as well the GDOME core headers. 62 */ 63#ifdef XML_LIBXML_GDOME_SUPPORT 64 65#include <libgdome/gdome.h> 66#include <libgdome/gdome-libxml-util.h> 67 68#endif 69 70/* XML::LibXML stuff */ 71#include "perl-libxml-mm.h" 72#include "perl-libxml-sax.h" 73 74#include "dom.h" 75#include "xpath.h" 76#include "xpathcontext.h" 77 78#ifdef __cplusplus 79} 80#endif 81 82 83#define TEST_PERL_FLAG(flag) \ 84 SvTRUE(perl_get_sv(flag, FALSE)) ? 1 : 0 85 86#ifdef HAVE_READER_SUPPORT 87#define LIBXML_READER_TEST_ELEMENT(reader,name,nsURI) \ 88 (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) && \ 89 ((!nsURI && !name) \ 90 || \ 91 (!nsURI && xmlStrcmp((const xmlChar*)name, xmlTextReaderConstName(reader) ) == 0 ) \ 92 || \ 93 (nsURI && xmlStrcmp((const xmlChar*)nsURI, xmlTextReaderConstNamespaceUri(reader))==0 \ 94 && \ 95 (!name || xmlStrcmp((const xmlChar*)name, xmlTextReaderConstLocalName(reader)) == 0))) 96#endif 97 98/* this should keep the default */ 99static xmlExternalEntityLoader LibXML_old_ext_ent_loader = NULL; 100 101 102/* **************************************************************** 103 * Error handler 104 * **************************************************************** */ 105 106/* If threads-support is working correctly in libxml2 then 107 * this method will be called with the correct thread-context */ 108void 109LibXML_error_handler_ctx(void * ctxt, const char * msg, ...) 110{ 111 va_list args; 112 SV * saved_error = (SV *) ctxt; 113 114 /* If saved_error is null we croak with the error */ 115 if( NULL == saved_error ) { 116 SV * sv = sv_2mortal(newSV(0)); 117 va_start(args, msg); 118 /* vfprintf(stderr, msg, args); */ 119 sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL); 120 va_end(args); 121 croak("%s", SvPV_nolen(sv)); 122 /* Otherwise, save the error */ 123 } else { 124 va_start(args, msg); 125 /* vfprintf(stderr, msg, args); */ 126 sv_vcatpvfn(saved_error, msg, strlen(msg), &args, NULL, 0, NULL); 127 va_end(args); 128 } 129} 130 131static void 132LibXML_validity_error_ctx(void * ctxt, const char *msg, ...) 133{ 134 va_list args; 135 SV * saved_error = (SV *) ctxt; 136 137 /* If saved_error is null we croak with the error */ 138 if( NULL == saved_error ) { 139 SV * sv = sv_2mortal(newSV(0)); 140 va_start(args, msg); 141 sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL); 142 va_end(args); 143 croak("%s", SvPV_nolen(sv)); 144 /* Otherwise, save the error */ 145 } else { 146 va_start(args, msg); 147 sv_vcatpvfn(saved_error, msg, strlen(msg), &args, NULL, 0, NULL); 148 va_end(args); 149 } 150} 151 152static void 153LibXML_validity_warning_ctx(void * ctxt, const char *msg, ...) 154{ 155 va_list args; 156 SV * saved_error = (SV *) ctxt; 157 STRLEN len; 158 159 /* If saved_error is null we croak with the error */ 160 if( NULL == saved_error ) { 161 SV * sv = sv_2mortal(newSV(0)); 162 va_start(args, msg); 163 sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL); 164 va_end(args); 165 croak("LibXML_validity_warning_ctx internal error: context was null (%s)", SvPV_nolen(sv)); 166 /* Otherwise, give the warning */ 167 } else { 168 va_start(args, msg); 169 sv_vcatpvfn(saved_error, msg, strlen(msg), &args, NULL, 0, NULL); 170 va_end(args); 171 warn("validation error: %s", SvPV(saved_error, len)); 172 } 173} 174 175static void 176LibXML_init_error_ctx(SV * saved_error) 177{ 178 xmlSetGenericErrorFunc((void *) saved_error, (xmlGenericErrorFunc) LibXML_error_handler_ctx); 179} 180 181static int 182LibXML_will_die_ctx(SV * saved_error, int recover) 183{ 184 if( 0 < SvCUR( saved_error ) ) { 185 if ( recover == 0 ) { 186 return 1; 187 } 188 } 189 return 0; 190} 191 192 193static void 194LibXML_report_error_ctx(SV * saved_error, int recover) 195{ 196 if( 0 < SvCUR( saved_error ) ) { 197 if( recover ) { 198 if ( recover == 1 ) { 199 warn("%s", SvPV_nolen(saved_error)); 200 } /* else recover silently */ 201 } else { 202 croak("%s", SvPV_nolen(saved_error)); 203 } 204 } 205} 206 207#ifdef HAVE_READER_SUPPORT 208static void 209LibXML_reader_error_handler(void * ctxt, 210 const char * msg, 211 xmlParserSeverities severity, 212 xmlTextReaderLocatorPtr locator) 213{ 214 int line = xmlTextReaderLocatorLineNumber(locator); 215 xmlChar * filename = xmlTextReaderLocatorBaseURI(locator); 216 SV * msg_sv = sv_2mortal(C2Sv((xmlChar*) msg,NULL)); 217 SV * error = sv_2mortal(newSVpv("", 0)); 218 219 switch (severity) { 220 case XML_PARSER_SEVERITY_VALIDITY_WARNING: 221 sv_catpv(error, "Validity WARNING"); 222 break; 223 case XML_PARSER_SEVERITY_WARNING: 224 sv_catpv(error, "Reader WARNING"); 225 break; 226 case XML_PARSER_SEVERITY_VALIDITY_ERROR: 227 sv_catpv(error, "Validity ERROR"); 228 break; 229 case XML_PARSER_SEVERITY_ERROR: 230 sv_catpv(error, "Reader ERROR"); 231 break; 232 } 233 if (filename) { 234 sv_catpvf(error, " in %s", filename); 235 xmlFree(filename); 236 } 237 if (line >= 0) { 238 sv_catpvf(error, " at line %d", line); 239 } 240 sv_catpvf(error, ": %s", SvPV_nolen(msg_sv)); 241 if (severity == XML_PARSER_SEVERITY_VALIDITY_WARNING || 242 severity == XML_PARSER_SEVERITY_WARNING ) { 243 warn("%s", SvPV_nolen(error)); 244 } else { 245 SV * error_sv = (SV*) ctxt; 246 if (error_sv) { 247 sv_catpvf(error_sv, "%s ", SvPV_nolen(error)); 248 } else { 249 croak("%s",SvPV_nolen(error)); 250 } 251 } 252} 253 254static void 255LibXML_report_reader_error(xmlTextReaderPtr reader) 256{ 257 SV * error_sv = NULL; 258 xmlTextReaderErrorFunc f = NULL; 259 260 xmlTextReaderGetErrorHandler(reader, &f, (void **) &error_sv); 261 if ( error_sv && SvOK( error_sv) && 0 < SvCUR( error_sv ) ) { 262 croak("%s", SvPV_nolen(error_sv)); 263 } 264} 265#endif /* HAVE_READER_SUPPORT */ 266 267static int 268LibXML_get_recover(HV * real_obj) 269{ 270 SV** item = hv_fetch( real_obj, "XML_LIBXML_RECOVER", 18, 0 ); 271 return ( item != NULL && SvTRUE(*item) ) ? SvIV(*item) : 0; 272} 273 274static SV * 275LibXML_NodeToSv(HV * real_obj, xmlNodePtr real_doc) 276{ 277 SV** item = hv_fetch( real_obj, "XML_LIBXML_GDOME", 16, 0 ); 278 279 if ( item != NULL && SvTRUE(*item) ) { 280 return PmmNodeToGdomeSv(real_doc); 281 } 282 else { 283 return PmmNodeToSv(real_doc, NULL); 284 } 285} 286 287/* **************************************************************** 288 * IO callbacks 289 * **************************************************************** */ 290 291int 292LibXML_read_perl (SV * ioref, char * buffer, int len) 293{ 294 dTHX; 295 dSP; 296 297 int cnt; 298 SV * read_results; 299 STRLEN read_length; 300 char * chars; 301 SV * tbuff = NEWSV(0,len); 302 SV * tsize = newSViv(len); 303 304 ENTER; 305 SAVETMPS; 306 307 PUSHMARK(SP); 308 EXTEND(SP, 3); 309 PUSHs(ioref); 310 PUSHs(sv_2mortal(tbuff)); 311 PUSHs(sv_2mortal(tsize)); 312 PUTBACK; 313 314 if (sv_isobject(ioref)) { 315 cnt = call_method("read", G_SCALAR | G_EVAL); 316 } 317 else { 318 cnt = call_pv("XML::LibXML::__read", G_SCALAR | G_EVAL); 319 } 320 321 SPAGAIN; 322 323 if (cnt != 1) { 324 croak("read method call failed"); 325 } 326 327 if (SvTRUE(ERRSV)) { 328 croak("read on filehandle failed: %s", SvPV_nolen(ERRSV)); 329 POPs ; 330 } 331 332 read_results = POPs; 333 334 if (!SvOK(read_results)) { 335 croak("read error"); 336 } 337 338 read_length = SvIV(read_results); 339 340 chars = SvPV(tbuff, read_length); 341 strncpy(buffer, chars, read_length); 342 343 PUTBACK; 344 FREETMPS; 345 LEAVE; 346 347 return read_length; 348} 349 350/* used only by Reader */ 351int 352LibXML_close_perl (SV * ioref) 353{ 354 SvREFCNT_dec(ioref); 355 return 0; 356} 357 358int 359LibXML_input_match(char const * filename) 360{ 361 int results; 362 int count; 363 SV * res; 364 365 results = 0; 366 367 { 368 dTHX; 369 dSP; 370 371 ENTER; 372 SAVETMPS; 373 374 PUSHMARK(SP); 375 EXTEND(SP, 1); 376 PUSHs(sv_2mortal(newSVpv((char*)filename, 0))); 377 PUTBACK; 378 379 count = call_pv("XML::LibXML::InputCallback::_callback_match", 380 G_SCALAR | G_EVAL); 381 382 SPAGAIN; 383 384 if (count != 1) { 385 croak("match callback must return a single value"); 386 } 387 388 if (SvTRUE(ERRSV)) { 389 croak("input match callback died: %s", SvPV_nolen(ERRSV)); 390 POPs ; 391 } 392 393 res = POPs; 394 395 if (SvTRUE(res)) { 396 results = 1; 397 } 398 399 PUTBACK; 400 FREETMPS; 401 LEAVE; 402 } 403 return results; 404} 405 406void * 407LibXML_input_open(char const * filename) 408{ 409 SV * results; 410 int count; 411 412 dTHX; 413 dSP; 414 415 ENTER; 416 SAVETMPS; 417 418 PUSHMARK(SP); 419 EXTEND(SP, 1); 420 PUSHs(sv_2mortal(newSVpv((char*)filename, 0))); 421 PUTBACK; 422 423 count = call_pv("XML::LibXML::InputCallback::_callback_open", 424 G_SCALAR | G_EVAL); 425 426 SPAGAIN; 427 428 if (count != 1) { 429 croak("open callback must return a single value"); 430 } 431 432 if (SvTRUE(ERRSV)) { 433 croak("input callback died: %s", SvPV_nolen(ERRSV)); 434 POPs ; 435 } 436 437 results = POPs; 438 439 SvREFCNT_inc(results); 440 441 PUTBACK; 442 FREETMPS; 443 LEAVE; 444 445 return (void *)results; 446} 447 448int 449LibXML_input_read(void * context, char * buffer, int len) 450{ 451 STRLEN res_len; 452 const char * output; 453 SV * ctxt; 454 455 res_len = 0; 456 ctxt = (SV *)context; 457 458 { 459 int count; 460 461 dTHX; 462 dSP; 463 464 ENTER; 465 SAVETMPS; 466 467 PUSHMARK(SP); 468 EXTEND(SP, 2); 469 PUSHs(ctxt); 470 PUSHs(sv_2mortal(newSViv(len))); 471 PUTBACK; 472 473 count = call_pv("XML::LibXML::InputCallback::_callback_read", 474 G_SCALAR | G_EVAL); 475 476 SPAGAIN; 477 478 if (count != 1) { 479 croak("read callback must return a single value"); 480 } 481 482 if (SvTRUE(ERRSV)) { 483 croak("read callback died: %s", SvPV_nolen(ERRSV)); 484 POPs ; 485 } 486 487 output = POPp; 488 if (output != NULL) { 489 res_len = strlen(output); 490 if (res_len) { 491 strncpy(buffer, output, res_len); 492 } 493 else { 494 buffer[0] = 0; 495 } 496 } 497 498 PUTBACK; 499 FREETMPS; 500 LEAVE; 501 } 502 return res_len; 503} 504 505void 506LibXML_input_close(void * context) 507{ 508 SV * ctxt; 509 510 ctxt = (SV *)context; 511 512 { 513 dTHX; 514 dSP; 515 516 ENTER; 517 SAVETMPS; 518 519 PUSHMARK(SP); 520 EXTEND(SP, 1); 521 PUSHs(ctxt); 522 PUTBACK; 523 524 call_pv("XML::LibXML::InputCallback::_callback_close", 525 G_SCALAR | G_EVAL | G_DISCARD); 526 527 SvREFCNT_dec(ctxt); 528 529 if (SvTRUE(ERRSV)) { 530 croak("close callback died: %s", SvPV_nolen(ERRSV)); 531 } 532 533 FREETMPS; 534 LEAVE; 535 } 536} 537 538int 539LibXML_output_write_handler(void * ioref, char * buffer, int len) 540{ 541 if ( buffer != NULL && len > 0) { 542 dTHX; 543 dSP; 544 545 SV * tbuff = newSVpv(buffer,len); 546 SV * tsize = newSViv(len); 547 548 549 ENTER; 550 SAVETMPS; 551 552 PUSHMARK(SP); 553 EXTEND(SP, 3); 554 PUSHs((SV*)ioref); 555 PUSHs(sv_2mortal(tbuff)); 556 PUSHs(sv_2mortal(tsize)); 557 PUTBACK; 558 559 call_pv("XML::LibXML::__write", G_SCALAR | G_EVAL | G_DISCARD ); 560 561 if (SvTRUE(ERRSV)) { 562 croak("write method call died: %s", SvPV_nolen(ERRSV)); 563 } 564 565 FREETMPS; 566 LEAVE; 567 } 568 return len; 569} 570 571int 572LibXML_output_close_handler( void * handler ) 573{ 574 return 1; 575} 576 577xmlParserInputPtr 578LibXML_load_external_entity( 579 const char * URL, 580 const char * ID, 581 xmlParserCtxtPtr ctxt) 582{ 583 SV * self; 584 HV * real_obj; 585 SV ** func; 586 int count; 587 SV * results; 588 STRLEN results_len; 589 const char * results_pv; 590 xmlParserInputBufferPtr input_buf; 591 592 if (ctxt->_private == NULL) { 593 return xmlNewInputFromFile(ctxt, URL); 594 } 595 596 if (URL == NULL) { 597 URL = ""; 598 } 599 if (ID == NULL) { 600 ID = ""; 601 } 602 603 self = (SV *)ctxt->_private; 604 real_obj = (HV *)SvRV(self); 605 func = hv_fetch(real_obj, "ext_ent_handler", 15, 0); 606 607 if (func) { 608 dTHX; 609 dSP; 610 611 ENTER; 612 SAVETMPS; 613 614 PUSHMARK(SP) ; 615 XPUSHs(sv_2mortal(newSVpv((char*)URL, 0))); 616 XPUSHs(sv_2mortal(newSVpv((char*)ID, 0))); 617 PUTBACK; 618 619 count = call_sv(*func, G_SCALAR | G_EVAL); 620 621 SPAGAIN; 622 623 if (count == 0) { 624 croak("external entity handler did not return a value"); 625 } 626 627 if (SvTRUE(ERRSV)) { 628 croak("external entity callback died: %s", SvPV_nolen(ERRSV)); 629 POPs ; 630 } 631 632 results = POPs; 633 634 results_pv = SvPV(results, results_len); 635 input_buf = xmlParserInputBufferCreateMem( 636 results_pv, 637 results_len, 638 XML_CHAR_ENCODING_NONE 639 ); 640 641 PUTBACK; 642 FREETMPS; 643 LEAVE; 644 645 return xmlNewIOInputStream(ctxt, input_buf, XML_CHAR_ENCODING_NONE); 646 } 647 else { 648 if (URL == NULL) { 649 return NULL; 650 } 651 return xmlNewInputFromFile(ctxt, URL); 652 } 653} 654 655/* **************************************************************** 656 * Helper functions 657 * **************************************************************** */ 658 659HV* 660LibXML_init_parser( SV * self ) { 661 /* we fetch all switches and callbacks from the hash */ 662 HV* real_obj = NULL; 663 SV** item = NULL; 664 665 /* A NOTE ABOUT xmlInitParser(); */ 666 /* xmlInitParser() should be used only at startup and*/ 667 /* not for initializing a single parser. libxml2's */ 668 /* documentation is quite clear about this. If */ 669 /* something fails it is a problem elsewhere. Simply */ 670 /* resetting the entire module will lead to unwanted */ 671 /* results in server environments, such as if */ 672 /* mod_perl is used together with php's xml module. */ 673 /* calling xmlInitParser() here is definitly wrong! */ 674 /* xmlInitParser(); */ 675 676 xmlGetWarningsDefaultValue = 0; 677 678 if ( self != NULL ) { 679 /* first fetch the values from the hash */ 680 real_obj = (HV *)SvRV(self); 681 682 item = hv_fetch( real_obj, "XML_LIBXML_KEEP_BLANKS", 22, 0 ); 683 if ( item != NULL ) { 684 if ( SvTRUE(*item) ) 685 xmlKeepBlanksDefault(1); 686 else { 687 xmlKeepBlanksDefault(0); 688 } 689 } 690 else { 691 /* keep blanks on default */ 692 xmlKeepBlanksDefault(1); 693 } 694 695 item = hv_fetch( real_obj, "XML_LIBXML_PEDANTIC", 19, 0 ); 696 if ( item != NULL && SvTRUE(*item) ) { 697#ifdef LIBXML_THREAD_ENABLED 698#if LIBXML_VERSION != 20507 699 xmlThrDefPedanticParserDefaultValue( 1 ); 700#endif 701#endif 702 xmlPedanticParserDefaultValue = 1; 703 } 704 else { 705#ifdef LIBXML_THREAD_ENABLED 706#if LIBXML_VERSION != 20507 707 xmlThrDefPedanticParserDefaultValue( 0 ); 708#endif 709#endif 710 xmlPedanticParserDefaultValue = 0; 711 } 712 713 item = hv_fetch( real_obj, "XML_LIBXML_LINENUMBERS", 22, 0 ); 714 if ( item != NULL && SvTRUE(*item) ) { 715 xmlLineNumbersDefault( 1 ); 716 } 717 else { 718 xmlLineNumbersDefault( 0 ); 719 } 720 721 item = hv_fetch( real_obj, "XML_LIBXML_EXT_DTD", 18, 0 ); 722 if ( item != NULL && SvTRUE(*item) ) { 723 xmlLoadExtDtdDefaultValue |= 1; 724 725 item = hv_fetch( real_obj, "XML_LIBXML_VALIDATION", 21, 0 ); 726 if ( item != NULL && SvTRUE(*item) ) { 727 xmlDoValidityCheckingDefaultValue = 1; 728 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS; 729 } 730 else { 731 xmlDoValidityCheckingDefaultValue = 0; 732 } 733 item = hv_fetch( real_obj, "XML_LIBXML_COMPLETE_ATTR", 24, 0 ); 734 if (item != NULL && SvTRUE(*item)) { 735 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS; 736 } 737 else { 738 xmlLoadExtDtdDefaultValue ^= XML_COMPLETE_ATTRS; 739 } 740 741 item = hv_fetch( real_obj, "XML_LIBXML_EXPAND_ENTITIES", 26, 0 ); 742 if ( item != NULL ) { 743 if ( SvTRUE(*item) ) { 744 xmlSubstituteEntitiesDefaultValue = 1; 745 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS; 746 } 747 else { 748 xmlSubstituteEntitiesDefaultValue = 0; 749 } 750 } 751 else { 752 xmlSubstituteEntitiesDefaultValue = 1; 753 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS; 754 } 755 } 756 else { 757 /* xmlLoadExtDtdDefaultValue ^= 1;*/ 758 xmlLoadExtDtdDefaultValue = 0; 759 } 760 761 item = hv_fetch(real_obj, "ext_ent_handler", 15, 0); 762 if ( item != NULL && SvTRUE(*item)) { 763 LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader(); 764 xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_load_external_entity ); 765 } 766 else { 767 item = hv_fetch( real_obj, "XML_LIBXML_NONET", 16, 0 ); 768 if (item != NULL && SvTRUE(*item)) { 769 LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader(); 770 xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader ); 771 } 772 /* LibXML_old_ext_ent_loader = NULL; */ 773 } 774 } 775 776 return real_obj; 777} 778 779void 780LibXML_cleanup_parser() { 781 xmlSubstituteEntitiesDefaultValue = 1; 782 xmlKeepBlanksDefaultValue = 1; 783 xmlGetWarningsDefaultValue = 0; 784 xmlLoadExtDtdDefaultValue = 5; 785 xmlPedanticParserDefaultValue = 0; 786 xmlLineNumbersDefault( 0 ); 787 xmlDoValidityCheckingDefaultValue = 0; 788 789 if (LibXML_old_ext_ent_loader != NULL ) { 790 xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_old_ext_ent_loader ); 791 } 792} 793 794int 795LibXML_test_node_name( xmlChar * name ) 796{ 797 xmlChar * cur = name; 798 int tc = 0; 799 int len = 0; 800 801 if ( cur == NULL || *cur == 0 ) { 802 /* warn("name is empty" ); */ 803 return(0); 804 } 805 806 tc = domParseChar( cur, &len ); 807 808 if ( !( IS_LETTER( tc ) || (tc == '_') || (tc == ':')) ) { 809 /* warn( "is not a letter\n" ); */ 810 return(0); 811 } 812 813 tc = 0; 814 cur += len; 815 816 while (*cur != 0 ) { 817 tc = domParseChar( cur, &len ); 818 819 if (!(IS_LETTER(tc) || IS_DIGIT(tc) || (tc == '_') || 820 (tc == '-') || (tc == ':') || (tc == '.') || 821 IS_COMBINING(tc) || IS_EXTENDER(tc)) ) { 822 /* warn( "is not a letter\n" ); */ 823 return(0); 824 } 825 tc = 0; 826 cur += len; 827 } 828 829 /* warn("name is ok"); */ 830 return(1); 831} 832 833/* **************************************************************** 834 * XPathContext helper functions 835 * **************************************************************** */ 836 837/* Temporary node pool: * 838 * Stores pnode in context node-pool hash table in order to preserve * 839 * at least one reference. * 840 * If pnode is NULL, only return current value for hashkey */ 841static SV* 842LibXML_XPathContext_pool ( xmlXPathContextPtr ctxt, void * hashkey, SV * pnode ) { 843 SV ** value; 844 SV * key; 845 STRLEN len; 846 char * strkey; 847 dTHX; 848 849 if (XPathContextDATA(ctxt)->pool == NULL) { 850 if (pnode == NULL) { 851 return &PL_sv_undef; 852 } else { 853 xs_warn("initializing node pool"); 854 XPathContextDATA(ctxt)->pool = newHV(); 855 } 856 } 857 858 key = newSViv((IV) hashkey); 859 strkey = SvPV(key, len); 860 if (pnode != NULL && !hv_exists(XPathContextDATA(ctxt)->pool,strkey,len)) { 861 value = hv_store(XPathContextDATA(ctxt)->pool,strkey,len, SvREFCNT_inc(pnode),0); 862 } else { 863 value = hv_fetch(XPathContextDATA(ctxt)->pool,strkey,len, 0); 864 } 865 SvREFCNT_dec(key); 866 867 if (value == NULL) { 868 return &PL_sv_undef; 869 } else { 870 return *value; 871 } 872} 873 874/* convert perl result structures to LibXML structures */ 875static xmlXPathObjectPtr 876LibXML_perldata_to_LibXMLdata(xmlXPathParserContextPtr ctxt, 877 SV* perl_result) { 878 dTHX; 879 880 if (!SvOK(perl_result)) { 881 return (xmlXPathObjectPtr)xmlXPathNewCString(""); 882 } 883 if (SvROK(perl_result) && 884 SvTYPE(SvRV(perl_result)) == SVt_PVAV) { 885 /* consider any array ref to be a nodelist */ 886 int i; 887 int length; 888 SV ** pnode; 889 AV * array_result; 890 xmlXPathObjectPtr ret; 891 892 ret = (xmlXPathObjectPtr) xmlXPathNewNodeSet((xmlNodePtr) NULL); 893 array_result = (AV*)SvRV(perl_result); 894 length = av_len(array_result); 895 for( i = 0; i <= length ; i++ ) { 896 pnode = av_fetch(array_result,i,0); 897 if (pnode != NULL && sv_isobject(*pnode) && 898 sv_derived_from(*pnode,"XML::LibXML::Node")) { 899 xmlXPathNodeSetAdd(ret->nodesetval, 900 (xmlNodePtr)PmmSvNode(*pnode)); 901 if(ctxt) { 902 LibXML_XPathContext_pool(ctxt->context, 903 PmmSvNode(*pnode), *pnode); 904 } 905 } else { 906 warn("XPathContext: ignoring non-node member of a nodelist"); 907 } 908 } 909 return ret; 910 } else if (sv_isobject(perl_result) && 911 (SvTYPE(SvRV(perl_result)) == SVt_PVMG)) 912 { 913 if (sv_derived_from(perl_result, "XML::LibXML::Node")) { 914 xmlNodePtr tmp_node; 915 xmlXPathObjectPtr ret; 916 917 ret = (xmlXPathObjectPtr)xmlXPathNewNodeSet(NULL); 918 tmp_node = (xmlNodePtr)PmmSvNode(perl_result); 919 xmlXPathNodeSetAdd(ret->nodesetval,tmp_node); 920 if(ctxt) { 921 LibXML_XPathContext_pool(ctxt->context, PmmSvNode(perl_result), 922 perl_result); 923 } 924 925 return ret; 926 } 927 else if (sv_isa(perl_result, "XML::LibXML::Boolean")) { 928 return (xmlXPathObjectPtr) 929 xmlXPathNewBoolean(SvIV(SvRV(perl_result))); 930 } 931 else if (sv_isa(perl_result, "XML::LibXML::Literal")) { 932 return (xmlXPathObjectPtr) 933 xmlXPathNewCString(SvPV_nolen(SvRV(perl_result))); 934 } 935 else if (sv_isa(perl_result, "XML::LibXML::Number")) { 936 return (xmlXPathObjectPtr) 937 xmlXPathNewFloat(SvNV(SvRV(perl_result))); 938 } 939 } else if (SvNOK(perl_result) || SvIOK(perl_result)) { 940 return (xmlXPathObjectPtr)xmlXPathNewFloat(SvNV(perl_result)); 941 } else { 942 return (xmlXPathObjectPtr) 943 xmlXPathNewCString(SvPV_nolen(perl_result)); 944 } 945 return NULL; 946} 947 948 949/* save XPath context and XPathContextDATA for recursion */ 950static xmlXPathContextPtr 951LibXML_save_context(xmlXPathContextPtr ctxt) 952{ 953 xmlXPathContextPtr copy; 954 copy = xmlMalloc(sizeof(xmlXPathContext)); 955 if (copy) { 956 /* backup ctxt */ 957 memcpy(copy, ctxt, sizeof(xmlXPathContext)); 958 /* clear namespaces so that they are not freed and overwritten 959 by configure_namespaces */ 960 ctxt->namespaces = NULL; 961 /* backup data */ 962 copy->user = xmlMalloc(sizeof(XPathContextData)); 963 if (XPathContextDATA(copy)) { 964 memcpy(XPathContextDATA(copy), XPathContextDATA(ctxt),sizeof(XPathContextData)); 965 /* clear ctxt->pool, so that it is not used freed during re-entrance */ 966 XPathContextDATA(ctxt)->pool = NULL; 967 } 968 } 969 return copy; 970} 971 972/* restore XPath context and XPathContextDATA from a saved copy */ 973static void 974LibXML_restore_context(xmlXPathContextPtr ctxt, xmlXPathContextPtr copy) 975{ 976 dTHX; 977 /* cleanup */ 978 if (XPathContextDATA(ctxt)) { 979 /* cleanup newly created pool */ 980 if (XPathContextDATA(ctxt)->pool != NULL && 981 SvOK(XPathContextDATA(ctxt)->pool)) { 982 SvREFCNT_dec((SV *)XPathContextDATA(ctxt)->pool); 983 } 984 } 985 if (ctxt->namespaces) { 986 /* free namespaces allocated during recursion */ 987 xmlFree( ctxt->namespaces ); 988 } 989 990 /* restore context */ 991 if (copy) { 992 /* 1st restore our data */ 993 if (XPathContextDATA(copy)) { 994 memcpy(XPathContextDATA(ctxt),XPathContextDATA(copy),sizeof(XPathContextData)); 995 xmlFree(XPathContextDATA(copy)); 996 copy->user = XPathContextDATA(ctxt); 997 } 998 /* now copy the rest */ 999 memcpy(ctxt, copy, sizeof(xmlXPathContext)); 1000 xmlFree(copy); 1001 } 1002} 1003 1004 1005/* **************************************************************** 1006 * Variable Lookup 1007 * **************************************************************** */ 1008/* Much of the code is borrowed from Matt Sergeant's XML::LibXSLT */ 1009static xmlXPathObjectPtr 1010LibXML_generic_variable_lookup(void* varLookupData, 1011 const xmlChar *name, 1012 const xmlChar *ns_uri) 1013{ 1014 xmlXPathObjectPtr ret; 1015 xmlXPathContextPtr ctxt; 1016 xmlXPathContextPtr copy; 1017 XPathContextDataPtr data; 1018 I32 count; 1019 dTHX; 1020 dSP; 1021 1022 ctxt = (xmlXPathContextPtr) varLookupData; 1023 if ( ctxt == NULL ) 1024 croak("XPathContext: missing xpath context"); 1025 data = XPathContextDATA(ctxt); 1026 if ( data == NULL ) 1027 croak("XPathContext: missing xpath context private data"); 1028 if ( data->varLookup == NULL || !SvROK(data->varLookup) || 1029 SvTYPE(SvRV(data->varLookup)) != SVt_PVCV ) 1030 croak("XPathContext: lost variable lookup function!"); 1031 1032 ENTER; 1033 SAVETMPS; 1034 PUSHMARK(SP); 1035 1036 XPUSHs( (data->varData != NULL) ? data->varData : &PL_sv_undef ); 1037 XPUSHs(sv_2mortal(C2Sv(name,NULL))); 1038 XPUSHs(sv_2mortal(C2Sv(ns_uri,NULL))); 1039 1040 /* save context to allow recursive usage of XPathContext */ 1041 copy = LibXML_save_context(ctxt); 1042 1043 PUTBACK ; 1044 count = perl_call_sv(data->varLookup, G_SCALAR|G_EVAL); 1045 SPAGAIN; 1046 1047 /* restore the xpath context */ 1048 LibXML_restore_context(ctxt, copy); 1049 1050 if (SvTRUE(ERRSV)) { 1051 POPs; 1052 croak("XPathContext: error coming back from variable lookup function. %s", SvPV_nolen(ERRSV)); 1053 } 1054 if (count != 1) croak("XPathContext: variable lookup function returned more than one argument!"); 1055 1056 ret = LibXML_perldata_to_LibXMLdata(NULL, POPs); 1057 1058 PUTBACK; 1059 FREETMPS; 1060 LEAVE; 1061 return ret; 1062} 1063 1064/* **************************************************************** 1065 * Generic Extension Function 1066 * **************************************************************** */ 1067/* Much of the code is borrowed from Matt Sergeant's XML::LibXSLT */ 1068static void 1069LibXML_generic_extension_function(xmlXPathParserContextPtr ctxt, int nargs) 1070{ 1071 xmlXPathObjectPtr obj,ret; 1072 xmlNodeSetPtr nodelist = NULL; 1073 int count; 1074 SV * perl_dispatch; 1075 int i; 1076 STRLEN len; 1077 ProxyNodePtr owner = NULL; 1078 SV *key; 1079 char *strkey; 1080 const char *function, *uri; 1081 SV **perl_function; 1082 dTHX; 1083 dSP; 1084 SV * data; 1085 xmlXPathContextPtr copy; 1086 1087 /* warn("entered LibXML_generic_extension_function for %s\n",ctxt->context->function); */ 1088 data = (SV *) ctxt->context->funcLookupData; 1089 if (ctxt->context->funcLookupData == NULL || !SvROK(data) || 1090 SvTYPE(SvRV(data)) != SVt_PVHV) { 1091 croak("XPathContext: lost function lookup data structure!"); 1092 } 1093 1094 function = (char*) ctxt->context->function; 1095 uri = (char*) ctxt->context->functionURI; 1096 1097 key = newSVpvn("",0); 1098 if (uri && *uri) { 1099 sv_catpv(key, "{"); 1100 sv_catpv(key, (const char*)uri); 1101 sv_catpv(key, "}"); 1102 } 1103 sv_catpv(key, (const char*)function); 1104 strkey = SvPV(key, len); 1105 perl_function = 1106 hv_fetch((HV*)SvRV(data), strkey, len, 0); 1107 if ( perl_function == NULL || !SvOK(*perl_function) || 1108 !(SvPOK(*perl_function) || 1109 (SvROK(*perl_function) && 1110 SvTYPE(SvRV(*perl_function)) == SVt_PVCV))) { 1111 croak("XPathContext: lost perl extension function!"); 1112 } 1113 SvREFCNT_dec(key); 1114 1115 ENTER; 1116 SAVETMPS; 1117 PUSHMARK(SP); 1118 1119 XPUSHs(*perl_function); 1120 1121 /* set up call to perl dispatcher function */ 1122 for (i = 0; i < nargs; i++) { 1123 obj = (xmlXPathObjectPtr)valuePop(ctxt); 1124 switch (obj->type) { 1125 case XPATH_XSLT_TREE: 1126 case XPATH_NODESET: 1127 nodelist = obj->nodesetval; 1128 if ( nodelist ) { 1129 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::NodeList", 0))); 1130 XPUSHs(sv_2mortal(newSViv(nodelist->nodeNr))); 1131 if ( nodelist->nodeNr > 0 ) { 1132 int j; 1133 const char * cls = "XML::LibXML::Node"; 1134 xmlNodePtr tnode; 1135 SV * element; 1136 1137 len = nodelist->nodeNr; 1138 for( j = 0 ; j < len; j++){ 1139 tnode = nodelist->nodeTab[j]; 1140 if( tnode != NULL && tnode->doc != NULL) { 1141 owner = PmmOWNERPO(PmmNewNode((xmlNodePtr) tnode->doc)); 1142 } else { 1143 owner = NULL; 1144 } 1145 if (tnode->type == XML_NAMESPACE_DECL) { 1146 element = sv_newmortal(); 1147 cls = PmmNodeTypeName( tnode ); 1148 element = sv_setref_pv( element, 1149 (const char *)cls, 1150 (void *)xmlCopyNamespace((xmlNsPtr)tnode) 1151 ); 1152 } 1153 else { 1154 element = PmmNodeToSv(tnode, owner); 1155 } 1156 XPUSHs( sv_2mortal(element) ); 1157 } 1158 } 1159 } else { 1160 /* PP: We can't simply leave out an empty nodelist as Matt does! */ 1161 /* PP: The number of arguments must match! */ 1162 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::NodeList", 0))); 1163 XPUSHs(sv_2mortal(newSViv(0))); 1164 } 1165 /* prevent libxml2 from freeing the actual nodes */ 1166 if (obj->boolval) obj->boolval=0; 1167 break; 1168 case XPATH_BOOLEAN: 1169 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Boolean", 0))); 1170 XPUSHs(sv_2mortal(newSViv(obj->boolval))); 1171 break; 1172 case XPATH_NUMBER: 1173 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Number", 0))); 1174 XPUSHs(sv_2mortal(newSVnv(obj->floatval))); 1175 break; 1176 case XPATH_STRING: 1177 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Literal", 0))); 1178 XPUSHs(sv_2mortal(C2Sv(obj->stringval, 0))); 1179 break; 1180 default: 1181 warn("Unknown XPath return type (%d) in call to {%s}%s - assuming string", obj->type, uri, function); 1182 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Literal", 0))); 1183 XPUSHs(sv_2mortal(C2Sv(xmlXPathCastToString(obj), 0))); 1184 } 1185 xmlXPathFreeObject(obj); 1186 } 1187 1188 /* save context to allow recursive usage of XPathContext */ 1189 copy = LibXML_save_context(ctxt->context); 1190 1191 /* call perl dispatcher */ 1192 PUTBACK; 1193 perl_dispatch = sv_2mortal(newSVpv("XML::LibXML::XPathContext::_perl_dispatcher",0)); 1194 count = perl_call_sv(perl_dispatch, G_SCALAR|G_EVAL); 1195 SPAGAIN; 1196 1197 /* restore the xpath context */ 1198 LibXML_restore_context(ctxt->context, copy); 1199 1200 if (SvTRUE(ERRSV)) { 1201 POPs; 1202 croak("XPathContext: error coming back from perl-dispatcher in pm file. %s", SvPV_nolen(ERRSV)); 1203 } 1204 1205 if (count != 1) croak("XPathContext: perl-dispatcher in pm file returned more than one argument!"); 1206 1207 ret = LibXML_perldata_to_LibXMLdata(ctxt, POPs); 1208 1209 valuePush(ctxt, ret); 1210 PUTBACK; 1211 FREETMPS; 1212 LEAVE; 1213} 1214 1215static void 1216LibXML_configure_namespaces( xmlXPathContextPtr ctxt ) { 1217 xmlNodePtr node = ctxt->node; 1218 1219 if (ctxt->namespaces != NULL) { 1220 xmlFree( ctxt->namespaces ); 1221 ctxt->namespaces = NULL; 1222 } 1223 if (node != NULL) { 1224 if (node->type == XML_DOCUMENT_NODE) { 1225 ctxt->namespaces = xmlGetNsList( node->doc, 1226 xmlDocGetRootElement( node->doc ) ); 1227 } else { 1228 ctxt->namespaces = xmlGetNsList(node->doc, node); 1229 } 1230 ctxt->nsNr = 0; 1231 if (ctxt->namespaces != NULL) { 1232 while (ctxt->namespaces[ctxt->nsNr] != NULL) 1233 ctxt->nsNr++; 1234 } 1235 } 1236} 1237 1238static void 1239LibXML_configure_xpathcontext( xmlXPathContextPtr ctxt ) { 1240 xmlNodePtr node = PmmSvNode(XPathContextDATA(ctxt)->node); 1241 1242 if (node != NULL) { 1243 ctxt->doc = node->doc; 1244 } else { 1245 ctxt->doc = NULL; 1246 } 1247 ctxt->node = node; 1248 LibXML_configure_namespaces(ctxt); 1249} 1250 1251MODULE = XML::LibXML PACKAGE = XML::LibXML 1252 1253PROTOTYPES: DISABLE 1254 1255BOOT: 1256 LIBXML_TEST_VERSION 1257 xmlInitParser(); 1258 PmmSAXInitialize(aTHX); 1259 1260 xmlSetGenericErrorFunc( NULL , 1261 (xmlGenericErrorFunc)LibXML_error_handler_ctx); 1262 xmlDoValidityCheckingDefaultValue = 0; 1263 xmlSubstituteEntitiesDefaultValue = 1; 1264 xmlGetWarningsDefaultValue = 0; 1265 xmlKeepBlanksDefaultValue = 1; 1266 xmlLoadExtDtdDefaultValue = 5; 1267 xmlPedanticParserDefaultValue = 0; 1268 xmlLineNumbersDefault(0); 1269 xmlSetGenericErrorFunc(NULL, NULL); 1270#ifdef LIBXML_CATALOG_ENABLED 1271 /* xmlCatalogSetDebug(10); */ 1272 xmlInitializeCatalog(); /* use catalog data */ 1273#endif 1274 1275char * 1276LIBXML_DOTTED_VERSION() 1277 CODE: 1278 RETVAL = LIBXML_DOTTED_VERSION; 1279 OUTPUT: 1280 RETVAL 1281 1282 1283int 1284LIBXML_VERSION() 1285 CODE: 1286 RETVAL = LIBXML_VERSION; 1287 OUTPUT: 1288 RETVAL 1289 1290const char * 1291LIBXML_RUNTIME_VERSION() 1292 CODE: 1293 RETVAL = xmlParserVersion; 1294 OUTPUT: 1295 RETVAL 1296 1297void 1298END() 1299 CODE: 1300 xmlCleanupParser(); 1301 1302SV* 1303_parse_string(self, string, dir = &PL_sv_undef) 1304 SV * self 1305 SV * string 1306 SV * dir 1307 PREINIT: 1308 char * directory = NULL; 1309 STRLEN len; 1310 char * ptr; 1311 SV * saved_error = sv_2mortal(newSVpv("",0)); 1312 HV * real_obj; 1313 int well_formed; 1314 int valid; 1315 xmlDocPtr real_doc; 1316 int recover = 0; 1317 INIT: 1318 if (SvPOK(dir)) { 1319 directory = SvPV(dir, len); 1320 if (len <= 0) { 1321 directory = NULL; 1322 } 1323 } 1324 ptr = SvPV(string, len); 1325 if (len <= 0) { 1326 croak("Empty string\n"); 1327 XSRETURN_UNDEF; 1328 } 1329 CODE: 1330 RETVAL = &PL_sv_undef; 1331 LibXML_init_error_ctx(saved_error); 1332 real_obj = LibXML_init_parser(self); 1333 recover = LibXML_get_recover(real_obj); 1334 1335 { 1336 xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt((const char*)ptr, len); 1337 if (ctxt == NULL) { 1338 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1339 croak("Could not create memory parser context!\n"); 1340 } 1341 xs_warn( "context created\n"); 1342 1343 if ( directory != NULL ) { 1344 ctxt->directory = directory; 1345 } 1346 ctxt->_private = (void*)self; 1347 1348 /* make libxml2-2.6 display line number on error */ 1349 if ( ctxt->input != NULL ) { 1350 if (directory != NULL) { 1351 ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) directory); 1352 } else { 1353 ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) ""); 1354 } 1355 } 1356 1357 xs_warn( "context initialized\n" ); 1358 1359 { 1360#if LIBXML_VERSION > 20600 1361 SV** item = hv_fetch( real_obj, "XML_LIBXML_NSCLEAN", 18, 0 ); 1362 if ( item != NULL && SvTRUE(*item) ) { 1363 ctxt->options |= XML_PARSE_NSCLEAN; 1364 } 1365 item = hv_fetch( real_obj, "XML_LIBXML_NONET", 16, 0 ); 1366 if ( item != NULL && SvTRUE(*item) ) { 1367 ctxt->options |= XML_PARSE_NONET; 1368 } 1369#endif 1370 xmlParseDocument(ctxt); 1371 xs_warn( "document parsed \n"); 1372 } 1373 1374 ctxt->directory = NULL; 1375 well_formed = ctxt->wellFormed; 1376 valid = ctxt->valid; 1377 real_doc = ctxt->myDoc; 1378 ctxt->myDoc = NULL; 1379 xmlFreeParserCtxt(ctxt); 1380 } 1381 if ( real_doc != NULL ) { 1382 if (real_doc->URL != NULL) { /* free "" assigned above */ 1383 xmlFree((char*) real_doc->URL); 1384 real_doc->URL = NULL; 1385 } 1386 1387 if ( directory == NULL ) { 1388 SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)real_doc)); 1389 real_doc->URL = xmlStrdup((const xmlChar*)SvPV_nolen(newURI)); 1390 } else { 1391 real_doc->URL = xmlStrdup((const xmlChar*)directory); 1392 } 1393 if ( ! LibXML_will_die_ctx(saved_error, recover) && 1394 (recover || ( well_formed && 1395 ( !xmlDoValidityCheckingDefaultValue 1396 || ( valid || ( real_doc->intSubset == NULL 1397 && real_doc->extSubset == NULL )))))) { 1398 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 1399 } else { 1400 xmlFreeDoc(real_doc); 1401 } 1402 } 1403 1404 LibXML_cleanup_parser(); 1405 LibXML_report_error_ctx(saved_error, recover); 1406 OUTPUT: 1407 RETVAL 1408 1409int 1410_parse_sax_string(self, string) 1411 SV * self 1412 SV * string 1413 PREINIT: 1414 STRLEN len; 1415 char * ptr; 1416 SV * saved_error = sv_2mortal(newSVpv("",0)); 1417 HV * real_obj; 1418 int recover = 0; 1419 INIT: 1420 ptr = SvPV(string, len); 1421 if (len <= 0) { 1422 croak("Empty string\n"); 1423 XSRETURN_UNDEF; 1424 } 1425 CODE: 1426 RETVAL = 0; 1427 LibXML_init_error_ctx(saved_error); 1428 real_obj = LibXML_init_parser(self); 1429 recover = LibXML_get_recover(real_obj); 1430 1431 { 1432 xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt((const char*)ptr, len); 1433 if (ctxt == NULL) { 1434 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1435 croak("Could not create memory parser context!\n"); 1436 } 1437 xs_warn( "context created\n"); 1438 1439 PmmSAXInitContext( ctxt, self, saved_error ); 1440 xs_warn( "context initialized \n"); 1441 1442 { 1443 RETVAL = xmlParseDocument(ctxt); 1444 xs_warn( "document parsed \n"); 1445 } 1446 1447 PmmSAXCloseContext(ctxt); 1448 xmlFreeParserCtxt(ctxt); 1449 } 1450 1451 LibXML_cleanup_parser(); 1452 LibXML_report_error_ctx(saved_error, recover); 1453 OUTPUT: 1454 RETVAL 1455 1456SV* 1457_parse_fh(self, fh, dir = &PL_sv_undef) 1458 SV * self 1459 SV * fh 1460 SV * dir 1461 PREINIT: 1462 STRLEN len; 1463 char * directory = NULL; 1464 SV * saved_error = sv_2mortal(newSVpv("",0)); 1465 HV * real_obj; 1466 int well_formed; 1467 int valid; 1468 xmlDocPtr real_doc; 1469 int recover = 0; 1470 INIT: 1471 if (SvPOK(dir)) { 1472 directory = SvPV(dir, len); 1473 if (len <= 0) { 1474 directory = NULL; 1475 } 1476 } 1477 CODE: 1478 RETVAL = &PL_sv_undef; 1479 LibXML_init_error_ctx(saved_error); 1480 real_obj = LibXML_init_parser(self); 1481 recover = LibXML_get_recover(real_obj); 1482 1483 { 1484 int read_length; 1485 char buffer[1024]; 1486 xmlParserCtxtPtr ctxt; 1487 1488 read_length = LibXML_read_perl(fh, buffer, 4); 1489 if (read_length <= 0) { 1490 croak( "Empty Stream\n" ); 1491 } 1492 1493 ctxt = xmlCreatePushParserCtxt(NULL, NULL, buffer, read_length, NULL); 1494 if (ctxt == NULL) { 1495 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1496 croak("Could not create xml push parser context!\n"); 1497 } 1498 xs_warn( "context created\n"); 1499#if LIBXML_VERSION > 20600 1500 /* dictionaries not support yet */ 1501 ctxt->dictNames = 0; 1502#endif 1503 if ( directory != NULL ) { 1504 ctxt->directory = directory; 1505 } 1506 ctxt->_private = (void*)self; 1507 xs_warn( "context initialized \n"); 1508 { 1509 int ret; 1510#if LIBXML_VERSION > 20600 1511 SV** item = hv_fetch( real_obj, "XML_LIBXML_NSCLEAN", 18, 0 ); 1512 if ( item != NULL && SvTRUE(*item) ) { 1513 ctxt->options |= XML_PARSE_NSCLEAN; 1514 } 1515 item = hv_fetch( real_obj, "XML_LIBXML_NONET", 16, 0 ); 1516 if ( item != NULL && SvTRUE(*item) ) { 1517 ctxt->options |= XML_PARSE_NONET; 1518 } 1519#endif 1520 while ((read_length = LibXML_read_perl(fh, buffer, 1024))) { 1521 ret = xmlParseChunk(ctxt, buffer, read_length, 0); 1522 if ( ret != 0 ) { 1523 break; 1524 } 1525 } 1526 ret = xmlParseChunk(ctxt, buffer, 0, 1); 1527 xs_warn( "document parsed \n"); 1528 } 1529 1530 ctxt->directory = NULL; 1531 well_formed = ctxt->wellFormed; 1532 valid = ctxt->valid; 1533 real_doc = ctxt->myDoc; 1534 ctxt->myDoc = NULL; 1535 xmlFreeParserCtxt(ctxt); 1536 } 1537 1538 if ( real_doc != NULL ) { 1539 1540 if ( directory == NULL ) { 1541 SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)real_doc)); 1542 real_doc->URL = xmlStrdup((const xmlChar*)SvPV_nolen(newURI)); 1543 } else { 1544 real_doc->URL = xmlStrdup((const xmlChar*)directory); 1545 } 1546 1547 if ( recover || ( well_formed && 1548 ( !xmlDoValidityCheckingDefaultValue 1549 || ( valid || ( real_doc->intSubset == NULL 1550 && real_doc->extSubset == NULL ))))) { 1551 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 1552 } else { 1553 xmlFreeDoc(real_doc); 1554 } 1555 } 1556 1557 LibXML_cleanup_parser(); 1558 LibXML_report_error_ctx(saved_error, recover); 1559 OUTPUT: 1560 RETVAL 1561 1562void 1563_parse_sax_fh(self, fh, dir = &PL_sv_undef) 1564 SV * self 1565 SV * fh 1566 SV * dir 1567 PREINIT: 1568 STRLEN len; 1569 char * directory = NULL; 1570 SV * saved_error = sv_2mortal(newSVpv("",0)); 1571 HV * real_obj; 1572 int recover = 0; 1573 INIT: 1574 if (SvPOK(dir)) { 1575 directory = SvPV(dir, len); 1576 if (len <= 0) { 1577 directory = NULL; 1578 } 1579 } 1580 CODE: 1581 LibXML_init_error_ctx(saved_error); 1582 real_obj = LibXML_init_parser(self); 1583 recover = LibXML_get_recover(real_obj); 1584 1585 { 1586 int read_length; 1587 char buffer[1024]; 1588 xmlSAXHandlerPtr sax; 1589 xmlParserCtxtPtr ctxt; 1590 1591 read_length = LibXML_read_perl(fh, buffer, 4); 1592 if (read_length <= 0) { 1593 croak( "Empty Stream\n" ); 1594 } 1595 1596 sax = PSaxGetHandler(); 1597 ctxt = xmlCreatePushParserCtxt(sax, NULL, buffer, read_length, NULL); 1598 if (ctxt == NULL) { 1599 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1600 croak("Could not create xml push parser context!\n"); 1601 } 1602 xs_warn( "context created\n"); 1603 1604 if ( directory != NULL ) { 1605 ctxt->directory = directory; 1606 } 1607 PmmSAXInitContext( ctxt, self, saved_error ); 1608 xs_warn( "context initialized \n"); 1609 1610 { 1611 int ret; 1612 while ((read_length = LibXML_read_perl(fh, buffer, 1024))) { 1613 ret = xmlParseChunk(ctxt, buffer, read_length, 0); 1614 if ( ret != 0 ) { 1615 break; 1616 } 1617 } 1618 ret = xmlParseChunk(ctxt, buffer, 0, 1); 1619 xs_warn( "document parsed \n"); 1620 } 1621 1622 ctxt->directory = NULL; 1623 xmlFree(ctxt->sax); 1624 ctxt->sax = NULL; 1625 xmlFree(sax); 1626 PmmSAXCloseContext(ctxt); 1627 xmlFreeParserCtxt(ctxt); 1628 } 1629 1630 LibXML_cleanup_parser(); 1631 LibXML_report_error_ctx(saved_error, recover); 1632 1633SV* 1634_parse_file(self, filename_sv) 1635 SV * self 1636 SV * filename_sv 1637 PREINIT: 1638 STRLEN len; 1639 char * filename; 1640 SV * saved_error = sv_2mortal(newSVpv("",0)); 1641 HV * real_obj; 1642 int well_formed; 1643 int valid; 1644 xmlDocPtr real_doc; 1645 int recover = 0; 1646 INIT: 1647 filename = SvPV(filename_sv, len); 1648 if (len <= 0) { 1649 croak("Empty filename\n"); 1650 XSRETURN_UNDEF; 1651 } 1652 CODE: 1653 RETVAL = &PL_sv_undef; 1654 LibXML_init_error_ctx(saved_error); 1655 real_obj = LibXML_init_parser(self); 1656 recover = LibXML_get_recover(real_obj); 1657 1658 { 1659 xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename); 1660 if (ctxt == NULL) { 1661 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1662 croak("Could not create file parser context for file \"%s\": %s\n", 1663 filename, strerror(errno)); 1664 } 1665 xs_warn( "context created\n"); 1666 1667 ctxt->_private = (void*)self; 1668 xs_warn( "context initialized \n"); 1669 1670 { 1671#if LIBXML_VERSION > 20600 1672 SV** item = hv_fetch( real_obj, "XML_LIBXML_NSCLEAN", 18, 0 ); 1673 if ( item != NULL && SvTRUE(*item) ) { 1674 ctxt->options |= XML_PARSE_NSCLEAN; 1675 } 1676 item = hv_fetch( real_obj, "XML_LIBXML_NONET", 16, 0 ); 1677 if ( item != NULL && SvTRUE(*item) ) { 1678 ctxt->options |= XML_PARSE_NONET; 1679 } 1680#endif 1681 xmlParseDocument(ctxt); 1682 xs_warn( "document parsed \n"); 1683 } 1684 1685 well_formed = ctxt->wellFormed; 1686 valid = ctxt->valid; 1687 real_doc = ctxt->myDoc; 1688 ctxt->myDoc = NULL; 1689 xmlFreeParserCtxt(ctxt); 1690 } 1691 1692 if ( real_doc != NULL ) { 1693 1694 if ( recover || ( well_formed && 1695 ( !xmlDoValidityCheckingDefaultValue 1696 || ( valid || ( real_doc->intSubset == NULL 1697 && real_doc->extSubset == NULL ))))) { 1698 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 1699 } else { 1700 xmlFreeDoc(real_doc); 1701 } 1702 } 1703 1704 LibXML_cleanup_parser(); 1705 LibXML_report_error_ctx(saved_error, recover); 1706 OUTPUT: 1707 RETVAL 1708 1709void 1710_parse_sax_file(self, filename_sv) 1711 SV * self 1712 SV * filename_sv 1713 PREINIT: 1714 STRLEN len; 1715 char * filename; 1716 SV * saved_error = sv_2mortal(newSVpv("",0)); 1717 HV * real_obj; 1718 int recover = 0; 1719 INIT: 1720 filename = SvPV(filename_sv, len); 1721 if (len <= 0) { 1722 croak("Empty filename\n"); 1723 XSRETURN_UNDEF; 1724 } 1725 CODE: 1726 LibXML_init_error_ctx(saved_error); 1727 real_obj = LibXML_init_parser(self); 1728 recover = LibXML_get_recover(real_obj); 1729 1730 { 1731 xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename); 1732 if (ctxt == NULL) { 1733 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1734 croak("Could not create file parser context for file \"%s\": %s\n", 1735 filename, strerror(errno)); 1736 } 1737 xs_warn( "context created\n"); 1738 1739 ctxt->sax = PSaxGetHandler(); 1740 PmmSAXInitContext( ctxt, self, saved_error ); 1741 xs_warn( "context initialized \n"); 1742 1743 { 1744 xmlParseDocument(ctxt); 1745 xs_warn( "document parsed \n"); 1746 } 1747 1748 PmmSAXCloseContext(ctxt); 1749 xmlFreeParserCtxt(ctxt); 1750 } 1751 1752 LibXML_cleanup_parser(); 1753 LibXML_report_error_ctx(saved_error, recover); 1754 1755SV* 1756_parse_html_string(self, string, svURL, svEncoding, options = 0) 1757 SV * self 1758 SV * string 1759 SV * svURL 1760 SV * svEncoding 1761 int options 1762 PREINIT: 1763 STRLEN len; 1764 char * ptr; 1765 char* URL = NULL; 1766 char * encoding = NULL; 1767 SV * saved_error = sv_2mortal(newSVpv("",0)); 1768 HV * real_obj; 1769 htmlDocPtr real_doc; 1770 int recover = 0; 1771 INIT: 1772 ptr = SvPV(string, len); 1773 if (len <= 0) { 1774 croak("Empty string\n"); 1775 XSRETURN_UNDEF; 1776 } 1777 if (SvOK(svURL)) 1778 URL = SvPV_nolen( svURL ); 1779 if (SvOK(svEncoding)) 1780 encoding = SvPV_nolen( svEncoding ); 1781 CODE: 1782 RETVAL = &PL_sv_undef; 1783 LibXML_init_error_ctx(saved_error); 1784 real_obj = LibXML_init_parser(self); 1785 if (encoding == NULL && SvUTF8( string )) { 1786 encoding = "UTF-8"; 1787 } 1788 recover = LibXML_get_recover(real_obj); 1789#if LIBXML_VERSION >= 20627 1790 if (recover) options |= HTML_PARSE_RECOVER; 1791 real_doc = htmlReadDoc((xmlChar*)ptr, URL, encoding, options); 1792#else 1793 real_doc = htmlParseDoc((xmlChar*)ptr, encoding); 1794#endif 1795 if ( real_doc != NULL ) { 1796 if (real_doc->URL) xmlFree((xmlChar *)real_doc->URL); 1797 if (URL) { 1798 real_doc->URL = xmlStrdup((const xmlChar*) URL); 1799 } else { 1800 SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)real_doc)); 1801 real_doc->URL = xmlStrdup((const xmlChar*)SvPV_nolen(newURI)); 1802 } 1803 1804 /* This HTML memory parser doesn't use a ctxt; there is no "well-formed" 1805 * distinction, and if it manages to parse the HTML, it returns non-null. */ 1806 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 1807 } 1808 1809 LibXML_cleanup_parser(); 1810 LibXML_report_error_ctx(saved_error, recover); 1811 OUTPUT: 1812 RETVAL 1813 1814 1815SV* 1816_parse_html_file(self, filename_sv, svURL, svEncoding, options = 0) 1817 SV * self 1818 SV * filename_sv 1819 SV * svURL 1820 SV * svEncoding 1821 int options 1822 PREINIT: 1823 STRLEN len; 1824 char * filename; 1825 char * URL = NULL; 1826 char * encoding = NULL; 1827 SV * saved_error = sv_2mortal(newSVpv("",0)); 1828 HV * real_obj; 1829 htmlDocPtr real_doc; 1830 int recover = 0; 1831 INIT: 1832 filename = SvPV(filename_sv, len); 1833 if (len <= 0) { 1834 croak("Empty filename\n"); 1835 XSRETURN_UNDEF; 1836 } 1837 if (SvOK(svURL)) 1838 URL = SvPV_nolen( svURL ); 1839 if (SvOK(svEncoding)) 1840 encoding = SvPV_nolen( svEncoding ); 1841 CODE: 1842 RETVAL = &PL_sv_undef; 1843 LibXML_init_error_ctx(saved_error); 1844 real_obj = LibXML_init_parser(self); 1845 recover = LibXML_get_recover(real_obj); 1846#if LIBXML_VERSION >= 20627 1847 if (recover) options |= HTML_PARSE_RECOVER; 1848 real_doc = htmlReadFile((const char *)filename, 1849 encoding, 1850 options); 1851#else 1852 real_doc = htmlParseFile((const char *)filename, encoding); 1853#endif 1854 if ( real_doc != NULL ) { 1855 1856 /* This HTML file parser doesn't use a ctxt; there is no "well-formed" 1857 * distinction, and if it manages to parse the HTML, it returns non-null. */ 1858 if (URL) { 1859 if (real_doc->URL) xmlFree((xmlChar*) real_doc->URL); 1860 real_doc->URL = xmlStrdup((const xmlChar*) URL); 1861 } 1862 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 1863 1864 } 1865 1866 LibXML_cleanup_parser(); 1867 LibXML_report_error_ctx(saved_error, recover); 1868 OUTPUT: 1869 RETVAL 1870 1871SV* 1872_parse_html_fh(self, fh, svURL, svEncoding, options = 0) 1873 SV * self 1874 SV * fh 1875 SV * svURL 1876 SV * svEncoding 1877 int options 1878 PREINIT: 1879 SV * saved_error = sv_2mortal(newSVpv("",0)); 1880 HV * real_obj; 1881 htmlDocPtr real_doc; 1882 int well_formed; 1883 int recover = 0; 1884 char * URL = NULL; 1885#if LIBXML_VERSION >= 20627 1886 char * encoding = NULL; 1887#else 1888 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; 1889#endif 1890 INIT: 1891 if (SvOK(svURL)) 1892 URL = SvPV_nolen( svURL ); 1893#if LIBXML_VERSION >= 20627 1894 if (SvOK(svEncoding)) 1895 encoding = SvPV_nolen( svEncoding ); 1896#else 1897 if (SvOK(svEncoding)) 1898 enc = xmlParseCharEncoding(SvPV_nolen( svEncoding )); 1899#endif 1900 CODE: 1901 RETVAL = &PL_sv_undef; 1902 LibXML_init_error_ctx(saved_error); 1903 real_obj = LibXML_init_parser(self); 1904 recover = LibXML_get_recover(real_obj); 1905#if LIBXML_VERSION >= 20627 1906 if (recover) options |= HTML_PARSE_RECOVER; 1907 1908 real_doc = htmlReadIO((xmlInputReadCallback) LibXML_read_perl, 1909 NULL, 1910 (void *) fh, 1911 URL, 1912 encoding, 1913 options); 1914#else /* LIBXML_VERSION >= 20627 */ 1915 { 1916 int read_length; 1917 char buffer[1024]; 1918 htmlParserCtxtPtr ctxt; 1919 1920 read_length = LibXML_read_perl(fh, buffer, 4); 1921 if (read_length <= 0) { 1922 croak( "Empty Stream\n" ); 1923 } 1924 ctxt = htmlCreatePushParserCtxt(NULL, NULL, buffer, read_length, 1925 URL, enc); 1926 if (ctxt == NULL) { 1927 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 1928 croak("Could not create html push parser context!\n"); 1929 } 1930 ctxt->_private = (void*)self; 1931 { 1932 int ret; 1933 while ((read_length = LibXML_read_perl(fh, buffer, 1024))) { 1934 ret = htmlParseChunk(ctxt, buffer, read_length, 0); 1935 if ( ret != 0 ) { 1936 break; 1937 } 1938 } 1939 ret = htmlParseChunk(ctxt, buffer, 0, 1); 1940 } 1941 well_formed = ctxt->wellFormed; 1942 real_doc = ctxt->myDoc; 1943 ctxt->myDoc = NULL; 1944 htmlFreeParserCtxt(ctxt); 1945 } 1946#endif /* LIBXML_VERSION >= 20627 */ 1947 if ( real_doc != NULL ) { 1948 if (real_doc->URL) xmlFree((xmlChar*) real_doc->URL); 1949 if (URL) { 1950 real_doc->URL = xmlStrdup((const xmlChar*) URL); 1951 } else { 1952 SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)real_doc)); 1953 real_doc->URL = xmlStrdup((const xmlChar*)SvPV_nolen(newURI)); 1954 } 1955 1956 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 1957 } 1958 1959 LibXML_cleanup_parser(); 1960 LibXML_report_error_ctx(saved_error, recover); 1961 OUTPUT: 1962 RETVAL 1963 1964SV* 1965_parse_xml_chunk(self, svchunk, enc = &PL_sv_undef) 1966 SV * self 1967 SV * svchunk 1968 SV * enc 1969 PREINIT: 1970 STRLEN len; 1971 char * encoding = "UTF-8"; 1972 SV * saved_error = sv_2mortal(newSVpv("",0)); 1973 HV * real_obj; 1974 int recover = 0; 1975 xmlChar * chunk; 1976 xmlNodePtr rv = NULL; 1977 INIT: 1978 if (SvPOK(enc)) { 1979 encoding = SvPV(enc, len); 1980 if (len <= 0) { 1981 encoding = "UTF-8"; 1982 } 1983 } 1984 CODE: 1985 RETVAL = &PL_sv_undef; 1986 LibXML_init_error_ctx(saved_error); 1987 real_obj = LibXML_init_parser(self); 1988 1989 chunk = Sv2C(svchunk, (const xmlChar*)encoding); 1990 1991 if ( chunk != NULL ) { 1992 recover = LibXML_get_recover(real_obj); 1993 1994 rv = domReadWellBalancedString( NULL, chunk, recover ); 1995 1996 if ( rv != NULL ) { 1997 xmlNodePtr fragment= NULL; 1998 xmlNodePtr rv_end = NULL; 1999 2000 /* now we append the nodelist to a document 2001 fragment which is unbound to a Document!!!! */ 2002 2003 /* step 1: create the fragment */ 2004 fragment = xmlNewDocFragment( NULL ); 2005 RETVAL = LibXML_NodeToSv(real_obj, fragment); 2006 2007 /* step 2: set the node list to the fragment */ 2008 fragment->children = rv; 2009 rv_end = rv; 2010 while ( rv_end->next != NULL ) { 2011 rv_end->parent = fragment; 2012 rv_end = rv_end->next; 2013 } 2014 /* the following line is important, otherwise we'll have 2015 occasional segmentation faults 2016 */ 2017 rv_end->parent = fragment; 2018 fragment->last = rv_end; 2019 } 2020 2021 /* free the chunk we created */ 2022 xmlFree( chunk ); 2023 } 2024 2025 LibXML_cleanup_parser(); 2026 LibXML_report_error_ctx(saved_error, recover); 2027 2028 if (rv == NULL) { 2029 croak("_parse_xml_chunk: chunk parsing failed\n"); 2030 } 2031 OUTPUT: 2032 RETVAL 2033 2034void 2035_parse_sax_xml_chunk(self, svchunk, enc = &PL_sv_undef) 2036 SV * self 2037 SV * svchunk 2038 SV * enc 2039 PREINIT: 2040 STRLEN len; 2041 char * ptr; 2042 char * encoding = "UTF-8"; 2043 SV * saved_error = sv_2mortal(newSVpv("",0)); 2044 HV * real_obj; 2045 int recover = 0; 2046 xmlChar * chunk; 2047 int retCode = -1; 2048 xmlNodePtr nodes = NULL; 2049 xmlSAXHandlerPtr handler = NULL; 2050 INIT: 2051 if (SvPOK(enc)) { 2052 encoding = SvPV(enc, len); 2053 if (len <= 0) { 2054 encoding = "UTF-8"; 2055 } 2056 } 2057 ptr = SvPV(svchunk, len); 2058 if (len <= 0) { 2059 croak("Empty string\n"); 2060 } 2061 CODE: 2062 LibXML_init_error_ctx(saved_error); 2063 real_obj = LibXML_init_parser(self); 2064 recover = LibXML_get_recover(real_obj); 2065 2066 chunk = Sv2C(svchunk, (const xmlChar*)encoding); 2067 2068 if ( chunk != NULL ) { 2069 xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt((const char*)ptr, len); 2070 if (ctxt == NULL) { 2071 LibXML_report_error_ctx(saved_error, recover ? recover : 1); 2072 croak("Could not create memory parser context!\n"); 2073 } 2074 xs_warn( "context created\n"); 2075 2076 PmmSAXInitContext( ctxt, self, saved_error ); 2077 handler = PSaxGetHandler(); 2078 2079 retCode = xmlParseBalancedChunkMemory( NULL, 2080 handler, 2081 ctxt, 2082 0, 2083 chunk, 2084 &nodes ); 2085 2086 xmlFree( handler ); 2087 PmmSAXCloseContext(ctxt); 2088 xmlFreeParserCtxt(ctxt); 2089 2090 /* free the chunk we created */ 2091 xmlFree( chunk ); 2092 } 2093 2094 LibXML_cleanup_parser(); 2095 LibXML_report_error_ctx(saved_error, recover); 2096 2097 if (retCode == -1) { 2098 croak("_parse_sax_xml_chunk: chunk parsing failed\n"); 2099 } 2100 2101int 2102_processXIncludes(self, doc, options=0) 2103 SV * self 2104 SV * doc 2105 int options 2106 PREINIT: 2107 xmlDocPtr real_doc; 2108 SV * saved_error = sv_2mortal(newSVpv("",0)); 2109 HV * real_obj; 2110 int recover = 0; 2111 INIT: 2112 real_doc = (xmlDocPtr) PmmSvNode(doc); 2113 if (real_doc == NULL) { 2114 croak("No document to process!\n"); 2115 XSRETURN_UNDEF; 2116 } 2117 CODE: 2118 RETVAL = 0; 2119 LibXML_init_error_ctx(saved_error); 2120 real_obj = LibXML_init_parser(self); 2121 recover = LibXML_get_recover(real_obj); 2122 2123 RETVAL = xmlXIncludeProcessFlags(real_doc,options); 2124 2125 LibXML_cleanup_parser(); 2126 LibXML_report_error_ctx(saved_error, recover); 2127 2128 if ( RETVAL < 0 ) { 2129 croak( "unknown error during XInclude processing\n" ); 2130 XSRETURN_UNDEF; 2131 } else if ( RETVAL == 0 ) { 2132 RETVAL = 1; 2133 } 2134 OUTPUT: 2135 RETVAL 2136 2137SV* 2138_start_push(self, with_sax=0) 2139 SV * self 2140 int with_sax 2141 PREINIT: 2142 SV * saved_error = sv_2mortal(newSVpv("",0)); 2143 HV * real_obj; 2144 int recover = 0; 2145 xmlParserCtxtPtr ctxt = NULL; 2146 CODE: 2147 RETVAL = &PL_sv_undef; 2148 LibXML_init_error_ctx(saved_error); 2149 real_obj = LibXML_init_parser(self); 2150 recover = LibXML_get_recover(real_obj); 2151 2152 /* create empty context */ 2153 ctxt = xmlCreatePushParserCtxt( NULL, NULL, NULL, 0, NULL ); 2154#if LIBXML_VERSION > 20600 2155 { 2156 SV** item = hv_fetch( real_obj, "XML_LIBXML_NSCLEAN", 18, 0 ); 2157 if ( item != NULL && SvTRUE(*item) ) { 2158 ctxt->options |= XML_PARSE_NSCLEAN; 2159 } 2160 item = hv_fetch( real_obj, "XML_LIBXML_NONET", 16, 0 ); 2161 if ( item != NULL && SvTRUE(*item) ) { 2162 ctxt->options |= XML_PARSE_NONET; 2163 } 2164 } 2165#endif 2166 if ( with_sax == 1 ) { 2167 PmmSAXInitContext( ctxt, self, saved_error ); 2168 } 2169 2170 RETVAL = PmmContextSv( ctxt ); 2171 2172 LibXML_cleanup_parser(); 2173 LibXML_report_error_ctx(saved_error, recover); 2174 OUTPUT: 2175 RETVAL 2176 2177int 2178_push(self, pctxt, data) 2179 SV * self 2180 SV * pctxt 2181 SV * data 2182 PREINIT: 2183 SV * saved_error = sv_2mortal(newSVpv("",0)); 2184 HV * real_obj; 2185 int recover = 0; 2186 xmlParserCtxtPtr ctxt = NULL; 2187 STRLEN len = 0; 2188 char * chunk = NULL; 2189 INIT: 2190 ctxt = PmmSvContext( pctxt ); 2191 if ( ctxt == NULL ) { 2192 croak( "parser context already freed\n" ); 2193 XSRETURN_UNDEF; 2194 } 2195 if ( data == &PL_sv_undef ) { 2196 XSRETURN_UNDEF; 2197 } 2198 chunk = SvPV( data, len ); 2199 if ( len <= 0 ) { 2200 xs_warn( "empty string" ); 2201 XSRETURN_UNDEF; 2202 } 2203 CODE: 2204 RETVAL = 0; 2205 LibXML_init_error_ctx(saved_error); 2206 real_obj = LibXML_init_parser(self); 2207 recover = LibXML_get_recover(real_obj); 2208 2209 xmlParseChunk(ctxt, (const char *)chunk, len, 0); 2210 2211 LibXML_cleanup_parser(); 2212 LibXML_report_error_ctx(saved_error, recover); 2213 2214 if ( ctxt->wellFormed == 0 ) { 2215 croak( "XML not well-formed in xmlParseChunk\n" ); 2216 XSRETURN_UNDEF; 2217 } 2218 RETVAL = 1; 2219 OUTPUT: 2220 RETVAL 2221 2222SV* 2223_end_push(self, pctxt, restore) 2224 SV * self 2225 SV * pctxt 2226 int restore 2227 PREINIT: 2228 SV * saved_error = sv_2mortal(newSVpv("",0)); 2229 HV * real_obj; 2230 int well_formed; 2231 xmlParserCtxtPtr ctxt = NULL; 2232 xmlDocPtr real_doc = NULL; 2233 INIT: 2234 ctxt = PmmSvContext( pctxt ); 2235 if ( ctxt == NULL ) { 2236 croak( "parser context already freed\n" ); 2237 XSRETURN_UNDEF; 2238 } 2239 CODE: 2240 RETVAL = &PL_sv_undef; 2241 LibXML_init_error_ctx(saved_error); 2242 real_obj = LibXML_init_parser(self); 2243 2244 xmlParseChunk(ctxt, "", 0, 1); /* finish the parse */ 2245 xs_warn( "Finished with push parser\n" ); 2246 2247 well_formed = ctxt->wellFormed; 2248 real_doc = ctxt->myDoc; 2249 ctxt->myDoc = NULL; 2250 xmlFreeParserCtxt(ctxt); 2251 PmmNODE( SvPROXYNODE( pctxt ) ) = NULL; 2252 2253 if ( real_doc != NULL ) { 2254 if ( restore || well_formed ) { 2255 RETVAL = LibXML_NodeToSv( real_obj, (xmlNodePtr) real_doc ); 2256 } else { 2257 xmlFreeDoc(real_doc); 2258 real_doc = NULL; 2259 } 2260 } 2261 2262 LibXML_cleanup_parser(); 2263 LibXML_report_error_ctx(saved_error, restore); 2264 2265 if ( real_doc == NULL ){ 2266 croak( "no document found!\n" ); 2267 XSRETURN_UNDEF; 2268 } 2269 OUTPUT: 2270 RETVAL 2271 2272void 2273_end_sax_push(self, pctxt) 2274 SV * self 2275 SV * pctxt 2276 PREINIT: 2277 SV * saved_error = sv_2mortal(newSVpv("",0)); 2278 HV * real_obj; 2279 xmlParserCtxtPtr ctxt = NULL; 2280 INIT: 2281 ctxt = PmmSvContext( pctxt ); 2282 if ( ctxt == NULL ) { 2283 croak( "parser context already freed\n" ); 2284 } 2285 CODE: 2286 LibXML_init_error_ctx(saved_error); 2287 real_obj = LibXML_init_parser(self); 2288 2289 xmlParseChunk(ctxt, "", 0, 1); /* finish the parse */ 2290 xs_warn( "Finished with SAX push parser\n" ); 2291 2292 xmlFree(ctxt->sax); 2293 ctxt->sax = NULL; 2294 PmmSAXCloseContext(ctxt); 2295 xmlFreeParserCtxt(ctxt); 2296 PmmNODE( SvPROXYNODE( pctxt ) ) = NULL; 2297 2298 LibXML_cleanup_parser(); 2299 LibXML_report_error_ctx(saved_error, 0); 2300 2301SV* 2302import_GDOME( dummy, sv_gdome, deep=1 ) 2303 SV * dummy 2304 SV * sv_gdome 2305 int deep 2306 PREINIT: 2307 xmlNodePtr node = NULL; 2308 INIT: 2309 RETVAL = &PL_sv_undef; 2310#ifndef XML_LIBXML_GDOME_SUPPORT 2311 croak( "GDOME Support not compiled" ); 2312#endif 2313 if ( sv_gdome == NULL || sv_gdome == &PL_sv_undef ) { 2314 croak( "no XML::GDOME data found" ); 2315 } 2316#ifdef XML_LIBXML_GDOME_SUPPORT 2317 else { 2318 GdomeNode* gnode = NULL; 2319 gnode = (GdomeNode*)SvIV((SV*)SvRV( sv_gdome )); 2320 if ( gnode == NULL ) { 2321 croak( "no XML::GDOME data found (datastructure empty)" ); 2322 } 2323 2324 node = gdome_xml_n_get_xmlNode( gnode ); 2325 if ( node == NULL ) { 2326 croak( "no XML::LibXML node found in GDOME object" ); 2327 } 2328 } 2329#endif 2330 CODE: 2331 if ( node->type == XML_NAMESPACE_DECL ) { 2332 const char * CLASS = "XML::LibXML::Namespace"; 2333 RETVAL = sv_newmortal(); 2334 RETVAL = sv_setref_pv( RETVAL, 2335 CLASS, 2336 (void*)xmlCopyNamespace((xmlNsPtr)node) ); 2337 } 2338 else { 2339 RETVAL = PmmNodeToSv( PmmCloneNode( node, deep ), NULL ); 2340 } 2341 OUTPUT: 2342 RETVAL 2343 2344 2345SV* 2346export_GDOME( dummy, sv_libxml, deep=1 ) 2347 SV * dummy 2348 SV * sv_libxml 2349 int deep 2350 PREINIT: 2351 xmlNodePtr node = NULL, retnode = NULL; 2352 INIT: 2353 RETVAL = &PL_sv_undef; 2354#ifndef XML_LIBXML_GDOME_SUPPORT 2355 croak( "GDOME Support not configured!" ); 2356#endif 2357 if ( sv_libxml == NULL || sv_libxml == &PL_sv_undef ) { 2358 croak( "no XML::LibXML data found" ); 2359 } 2360 node = PmmSvNode( sv_libxml ); 2361 if ( node == NULL ) { 2362 croak( "no XML::LibXML data found (empty structure)" ); 2363 } 2364 CODE: 2365 retnode = PmmCloneNode( node, deep ); 2366 if ( retnode == NULL ) { 2367 croak( "Copy node failed" ); 2368 } 2369 2370 RETVAL = PmmNodeToGdomeSv( retnode ); 2371 OUTPUT: 2372 RETVAL 2373 2374 2375int 2376load_catalog( self, filename ) 2377 SV * self 2378 SV * filename 2379 PREINIT: 2380 const char * fn = (const char *) Sv2C(filename, NULL); 2381 INIT: 2382 if ( fn == NULL || xmlStrlen( (xmlChar *)fn ) == 0 ) { 2383 croak( "cannot load catalog" ); 2384 } 2385 CODE: 2386#ifdef LIBXML_CATALOG_ENABLED 2387 RETVAL = xmlLoadCatalog( fn ); 2388#else 2389 XSRETURN_UNDEF; 2390#endif 2391 OUTPUT: 2392 RETVAL 2393 2394 2395 2396int 2397_default_catalog( self, catalog ) 2398 SV * self 2399 SV * catalog 2400 PREINIT: 2401#ifdef LIBXML_CATALOG_ENABLED 2402 xmlCatalogPtr catal = (xmlCatalogPtr)SvIV(SvRV(catalog)); 2403#endif 2404 INIT: 2405 if ( catal == NULL ) { 2406 croak( "empty catalog\n" ); 2407 } 2408 CODE: 2409 warn( "this feature is not implemented" ); 2410 RETVAL = 0; 2411 OUTPUT: 2412 RETVAL 2413 2414MODULE = XML::LibXML PACKAGE = XML::LibXML::ParserContext 2415 2416void 2417DESTROY( self ) 2418 SV * self 2419 CODE: 2420 xs_warn( "DROP PARSER CONTEXT!" ); 2421 PmmContextREFCNT_dec( SvPROXYNODE( self ) ); 2422 2423 2424MODULE = XML::LibXML PACKAGE = XML::LibXML::Document 2425 2426SV * 2427_toString(self, format=0) 2428 xmlDocPtr self 2429 int format 2430 PREINIT: 2431 /* SV * saved_error = sv_2mortal(newSVpv("",0)); */ 2432 xmlChar *result=NULL; 2433 int len=0; 2434 SV* internalFlag = NULL; 2435 int oldTagFlag = xmlSaveNoEmptyTags; 2436 xmlDtdPtr intSubset = NULL; 2437 CODE: 2438 RETVAL = &PL_sv_undef; 2439 internalFlag = perl_get_sv("XML::LibXML::setTagCompression", 0); 2440 if( internalFlag ) { 2441 xmlSaveNoEmptyTags = SvTRUE(internalFlag); 2442 } 2443 2444 internalFlag = perl_get_sv("XML::LibXML::skipDTD", 0); 2445 if ( internalFlag && SvTRUE(internalFlag) ) { 2446 intSubset = xmlGetIntSubset( self ); 2447 if ( intSubset ) 2448 xmlUnlinkNode( (xmlNodePtr)intSubset ); 2449 } 2450 2451 /* LibXML_init_error_ctx(saved_error); */ 2452 2453 if ( format <= 0 ) { 2454 xs_warn( "use no formated toString!" ); 2455 xmlDocDumpMemory(self, &result, &len); 2456 } 2457 else { 2458 int t_indent_var = xmlIndentTreeOutput; 2459 xs_warn( "use formated toString!" ); 2460 xmlIndentTreeOutput = 1; 2461 xmlDocDumpFormatMemory( self, &result, &len, format ); 2462 xmlIndentTreeOutput = t_indent_var; 2463 } 2464 2465 if ( intSubset != NULL ) { 2466 if (self->children == NULL) { 2467 xmlAddChild((xmlNodePtr) self, (xmlNodePtr) intSubset); 2468 } 2469 else { 2470 xmlAddPrevSibling(self->children, (xmlNodePtr) intSubset); 2471 } 2472 } 2473 2474 xmlSaveNoEmptyTags = oldTagFlag; 2475 2476 /* LibXML_report_error_ctx(saved_error, 0); */ 2477 2478 if (result == NULL) { 2479 xs_warn("Failed to convert doc to string"); 2480 XSRETURN_UNDEF; 2481 } else { 2482 /* warn("%s, %d\n",result, len); */ 2483 RETVAL = newSVpvn( (const char *)result, len ); 2484 /* C2Sv( result, self->encoding ); */ 2485 xmlFree(result); 2486 } 2487 OUTPUT: 2488 RETVAL 2489 2490int 2491toFH( self, filehandler, format=0 ) 2492 xmlDocPtr self 2493 SV * filehandler 2494 int format 2495 PREINIT: 2496 SV * saved_error = sv_2mortal(newSVpv("",0)); 2497 xmlOutputBufferPtr buffer; 2498 const xmlChar * encoding = NULL; 2499 xmlCharEncodingHandlerPtr handler = NULL; 2500 SV* internalFlag = NULL; 2501 int oldTagFlag = xmlSaveNoEmptyTags; 2502 xmlDtdPtr intSubset = NULL; 2503 int t_indent_var = xmlIndentTreeOutput; 2504 CODE: 2505 internalFlag = perl_get_sv("XML::LibXML::setTagCompression", 0); 2506 if( internalFlag ) { 2507 xmlSaveNoEmptyTags = SvTRUE(internalFlag); 2508 } 2509 2510 internalFlag = perl_get_sv("XML::LibXML::skipDTD", 0); 2511 if ( internalFlag && SvTRUE(internalFlag) ) { 2512 intSubset = xmlGetIntSubset( self ); 2513 if ( intSubset ) 2514 xmlUnlinkNode( (xmlNodePtr)intSubset ); 2515 } 2516 2517 xmlRegisterDefaultOutputCallbacks(); 2518 encoding = (self)->encoding; 2519 if ( encoding != NULL ) { 2520 if ( xmlParseCharEncoding((const char*)encoding) != XML_CHAR_ENCODING_UTF8) { 2521 handler = xmlFindCharEncodingHandler((const char*)encoding); 2522 } 2523 2524 } 2525 else { 2526 xs_warn("no encoding?"); 2527 } 2528 2529 buffer = xmlOutputBufferCreateIO( (xmlOutputWriteCallback) &LibXML_output_write_handler, 2530 (xmlOutputCloseCallback)&LibXML_output_close_handler, 2531 filehandler, 2532 handler ); 2533 2534 if ( format <= 0 ) { 2535 format = 0; 2536 xmlIndentTreeOutput = 0; 2537 } 2538 else { 2539 xmlIndentTreeOutput = 1; 2540 } 2541 2542 LibXML_init_error_ctx(saved_error); 2543 2544 RETVAL = xmlSaveFormatFileTo( buffer, 2545 self, 2546 (const char *) encoding, 2547 format); 2548 2549 if ( intSubset != NULL ) { 2550 if (self->children == NULL) { 2551 xmlAddChild((xmlNodePtr) self, (xmlNodePtr) intSubset); 2552 } 2553 else { 2554 xmlAddPrevSibling(self->children, (xmlNodePtr) intSubset); 2555 } 2556 } 2557 2558 xmlIndentTreeOutput = t_indent_var; 2559 xmlSaveNoEmptyTags = oldTagFlag; 2560 2561 LibXML_report_error_ctx(saved_error, 0); 2562 OUTPUT: 2563 RETVAL 2564 2565int 2566toFile( self, filename, format=0 ) 2567 xmlDocPtr self 2568 char * filename 2569 int format 2570 PREINIT: 2571 SV * saved_error = sv_2mortal(newSVpv("",0)); 2572 SV* internalFlag = NULL; 2573 int oldTagFlag = xmlSaveNoEmptyTags; 2574 CODE: 2575 internalFlag = perl_get_sv("XML::LibXML::setTagCompression", 0); 2576 if( internalFlag ) { 2577 xmlSaveNoEmptyTags = SvTRUE(internalFlag); 2578 } 2579 2580 LibXML_init_error_ctx(saved_error); 2581 2582 if ( format <= 0 ) { 2583 xs_warn( "use no formated toFile!" ); 2584 RETVAL = xmlSaveFile( filename, self ); 2585 } 2586 else { 2587 int t_indent_var = xmlIndentTreeOutput; 2588 xmlIndentTreeOutput = 1; 2589 RETVAL =xmlSaveFormatFile( filename, 2590 self, 2591 format); 2592 xmlIndentTreeOutput = t_indent_var; 2593 } 2594 2595 xmlSaveNoEmptyTags = oldTagFlag; 2596 2597 LibXML_report_error_ctx(saved_error, 0); 2598 2599 if ( RETVAL > 0 ) 2600 RETVAL = 1; 2601 else 2602 XSRETURN_UNDEF; 2603 OUTPUT: 2604 RETVAL 2605 2606SV * 2607toStringHTML(self) 2608 xmlDocPtr self 2609 ALIAS: 2610 XML::LibXML::Document::serialize_html = 1 2611 PREINIT: 2612 SV * saved_error = sv_2mortal(newSVpv("",0)); 2613 xmlChar *result=NULL; 2614 STRLEN len = 0; 2615 CODE: 2616 xs_warn( "use no formated toString!" ); 2617 LibXML_init_error_ctx(saved_error); 2618 htmlDocDumpMemory(self, &result, (int*)&len); 2619 2620 LibXML_report_error_ctx(saved_error, 0); 2621 2622 if (result == NULL) { 2623 XSRETURN_UNDEF; 2624 } else { 2625 /* warn("%s, %d\n",result, len); */ 2626 RETVAL = newSVpvn((char *)result, (STRLEN)len); 2627 xmlFree(result); 2628 } 2629 OUTPUT: 2630 RETVAL 2631 2632 2633const char * 2634URI( self ) 2635 xmlDocPtr self 2636 ALIAS: 2637 XML::LibXML::Document::documentURI = 1 2638 CODE: 2639 RETVAL = (const char*)xmlStrdup(self->URL ); 2640 OUTPUT: 2641 RETVAL 2642 2643void 2644setBaseURI( self, new_URI ) 2645 xmlDocPtr self 2646 char * new_URI 2647 CODE: 2648 if (new_URI) { 2649 xmlFree((xmlChar*)self->URL ); 2650 self->URL = xmlStrdup((const xmlChar*)new_URI); 2651 } 2652 2653 2654SV* 2655createDocument( CLASS, version="1.0", encoding=NULL ) 2656 char * CLASS 2657 char * version 2658 char * encoding 2659 ALIAS: 2660 XML::LibXML::Document::new = 1 2661 PREINIT: 2662 xmlDocPtr doc=NULL; 2663 CODE: 2664 doc = xmlNewDoc((const xmlChar*)version); 2665 if (encoding && *encoding != 0) { 2666 doc->encoding = (const xmlChar*)xmlStrdup((const xmlChar*)encoding); 2667 } 2668 RETVAL = PmmNodeToSv((xmlNodePtr)doc,NULL); 2669 OUTPUT: 2670 RETVAL 2671 2672SV* 2673createInternalSubset( self, Pname, extID, sysID ) 2674 xmlDocPtr self 2675 SV * Pname 2676 SV * extID 2677 SV * sysID 2678 PREINIT: 2679 xmlDtdPtr dtd = NULL; 2680 xmlChar * name = NULL; 2681 xmlChar * externalID = NULL; 2682 xmlChar * systemID = NULL; 2683 CODE: 2684 name = Sv2C( Pname, NULL ); 2685 if ( name == NULL ) { 2686 XSRETURN_UNDEF; 2687 } 2688 2689 externalID = Sv2C(extID, NULL); 2690 systemID = Sv2C(sysID, NULL); 2691 2692 dtd = xmlCreateIntSubset( self, name, externalID, systemID ); 2693 xmlFree(externalID); 2694 xmlFree(systemID); 2695 xmlFree(name); 2696 if ( dtd ) { 2697 RETVAL = PmmNodeToSv( (xmlNodePtr)dtd, PmmPROXYNODE(self) ); 2698 } 2699 else { 2700 XSRETURN_UNDEF; 2701 } 2702 OUTPUT: 2703 RETVAL 2704 2705SV* 2706createExternalSubset( self, Pname, extID, sysID ) 2707 xmlDocPtr self 2708 SV * Pname 2709 SV * extID 2710 SV * sysID 2711 PREINIT: 2712 xmlDtdPtr dtd = NULL; 2713 xmlChar * name = NULL; 2714 xmlChar * externalID = NULL; 2715 xmlChar * systemID = NULL; 2716 CODE: 2717 name = Sv2C( Pname, NULL ); 2718 if ( name == NULL ) { 2719 XSRETURN_UNDEF; 2720 } 2721 2722 externalID = Sv2C(extID, NULL); 2723 systemID = Sv2C(sysID, NULL); 2724 2725 dtd = xmlNewDtd( self, name, externalID, systemID ); 2726 2727 xmlFree(externalID); 2728 xmlFree(systemID); 2729 xmlFree(name); 2730 if ( dtd ) { 2731 RETVAL = PmmNodeToSv( (xmlNodePtr)dtd, PmmPROXYNODE(self) ); 2732 } 2733 else { 2734 XSRETURN_UNDEF; 2735 } 2736 OUTPUT: 2737 RETVAL 2738 2739SV* 2740createDTD( self, Pname, extID, sysID ) 2741 xmlDocPtr self 2742 SV * Pname 2743 SV * extID 2744 SV * sysID 2745 PREINIT: 2746 xmlDtdPtr dtd = NULL; 2747 xmlChar * name = NULL; 2748 xmlChar * externalID = NULL; 2749 xmlChar * systemID = NULL; 2750 CODE: 2751 name = Sv2C( Pname, NULL ); 2752 if ( name == NULL ) { 2753 XSRETURN_UNDEF; 2754 } 2755 2756 externalID = Sv2C(extID, NULL); 2757 systemID = Sv2C(sysID, NULL); 2758 2759 dtd = xmlNewDtd( NULL, name, externalID, systemID ); 2760 dtd->doc = self; 2761 2762 xmlFree(externalID); 2763 xmlFree(systemID); 2764 xmlFree(name); 2765 if ( dtd ) { 2766 RETVAL = PmmNodeToSv( (xmlNodePtr)dtd, PmmPROXYNODE(self) ); 2767 } 2768 else { 2769 XSRETURN_UNDEF; 2770 } 2771 OUTPUT: 2772 RETVAL 2773 2774SV* 2775createDocumentFragment( self ) 2776 xmlDocPtr self 2777 CODE: 2778 RETVAL = PmmNodeToSv(xmlNewDocFragment(self), PmmPROXYNODE(self)); 2779 OUTPUT: 2780 RETVAL 2781 2782SV* 2783createElement( self, name ) 2784 xmlDocPtr self 2785 SV* name 2786 PREINIT: 2787 xmlNodePtr newNode; 2788 xmlChar * elname = NULL; 2789 ProxyNodePtr docfrag = NULL; 2790 CODE: 2791 elname = nodeSv2C( name , (xmlNodePtr) self); 2792 if ( !LibXML_test_node_name( elname ) ) { 2793 xmlFree( elname ); 2794 croak( "bad name" ); 2795 } 2796 2797 newNode = xmlNewNode(NULL , elname); 2798 xmlFree(elname); 2799 if ( newNode != NULL ) { 2800 docfrag = PmmNewFragment( self ); 2801 newNode->doc = self; 2802 xmlAddChild(PmmNODE(docfrag), newNode); 2803 RETVAL = PmmNodeToSv(newNode,docfrag); 2804 } 2805 else { 2806 xs_warn( "no node created!" ); 2807 XSRETURN_UNDEF; 2808 } 2809 OUTPUT: 2810 RETVAL 2811 2812SV* 2813createRawElement( self, name ) 2814 xmlDocPtr self 2815 SV* name 2816 PREINIT: 2817 xmlNodePtr newNode; 2818 xmlChar * elname = NULL; 2819 ProxyNodePtr docfrag = NULL; 2820 CODE: 2821 elname = nodeSv2C( name , (xmlNodePtr) self); 2822 if ( !elname || xmlStrlen(elname) <= 0 ) { 2823 xmlFree( elname ); 2824 croak( "bad name" ); 2825 } 2826 2827 newNode = xmlNewDocNode(self,NULL , elname, NULL); 2828 xmlFree(elname); 2829 if ( newNode != NULL ) { 2830 docfrag = PmmNewFragment( self ); 2831 xmlAddChild(PmmNODE(docfrag), newNode); 2832 RETVAL = PmmNodeToSv(newNode,docfrag); 2833 } 2834 else { 2835 xs_warn( "no node created!" ); 2836 XSRETURN_UNDEF; 2837 } 2838 OUTPUT: 2839 RETVAL 2840 2841SV* 2842createElementNS( self, nsURI, name ) 2843 xmlDocPtr self 2844 SV * nsURI 2845 SV * name 2846 PREINIT: 2847 xmlChar * ename = NULL; 2848 xmlChar * prefix = NULL; 2849 xmlChar * localname = NULL; 2850 xmlChar * eURI = NULL; 2851 xmlNsPtr ns = NULL; 2852 ProxyNodePtr docfrag = NULL; 2853 xmlNodePtr newNode = NULL; 2854 CODE: 2855 ename = nodeSv2C( name , (xmlNodePtr) self ); 2856 if ( !LibXML_test_node_name( ename ) ) { 2857 xmlFree( ename ); 2858 croak( "bad name" ); 2859 } 2860 2861 eURI = Sv2C( nsURI , NULL ); 2862 2863 if ( eURI != NULL && xmlStrlen(eURI)!=0 ){ 2864 localname = xmlSplitQName2(ename, &prefix); 2865 if ( localname == NULL ) { 2866 localname = xmlStrdup( ename ); 2867 } 2868 2869 ns = xmlNewNs( NULL, eURI, prefix ); 2870 newNode = xmlNewDocNode( self, ns, localname, NULL ); 2871 newNode->nsDef = ns; 2872 2873 xmlFree(localname); 2874 } 2875 else { 2876 xs_warn( " ordinary element " ); 2877 /* ordinary element */ 2878 localname = ename; 2879 2880 newNode = xmlNewDocNode( self, NULL , localname, NULL ); 2881 } 2882 2883 docfrag = PmmNewFragment( self ); 2884 xmlAddChild(PmmNODE(docfrag), newNode); 2885 RETVAL = PmmNodeToSv(newNode, docfrag); 2886 2887 if ( prefix != NULL ) { 2888 xmlFree(prefix); 2889 } 2890 if ( eURI != NULL ) { 2891 xmlFree(eURI); 2892 } 2893 xmlFree(ename); 2894 OUTPUT: 2895 RETVAL 2896 2897SV* 2898createRawElementNS( self, nsURI, name ) 2899 xmlDocPtr self 2900 SV * nsURI 2901 SV * name 2902 PREINIT: 2903 xmlChar * ename = NULL; 2904 xmlChar * prefix = NULL; 2905 xmlChar * localname = NULL; 2906 xmlChar * eURI = NULL; 2907 xmlNsPtr ns = NULL; 2908 ProxyNodePtr docfrag = NULL; 2909 xmlNodePtr newNode = NULL; 2910 CODE: 2911 ename = nodeSv2C( name , (xmlNodePtr) self ); 2912 if ( !LibXML_test_node_name( ename ) ) { 2913 xmlFree( ename ); 2914 croak( "bad name" ); 2915 } 2916 2917 eURI = Sv2C( nsURI , NULL ); 2918 2919 if ( eURI != NULL && xmlStrlen(eURI)!=0 ){ 2920 localname = xmlSplitQName2(ename, &prefix); 2921 if ( localname == NULL ) { 2922 localname = xmlStrdup( ename ); 2923 } 2924 2925 newNode = xmlNewDocNode( self,NULL , localname, NULL ); 2926 2927 ns = xmlSearchNsByHref( self, newNode, eURI ); 2928 if ( ns == NULL ) { 2929 /* create a new NS if the NS does not already exists */ 2930 ns = xmlNewNs(newNode, eURI , prefix ); 2931 } 2932 2933 if ( ns == NULL ) { 2934 xmlFreeNode( newNode ); 2935 xmlFree(eURI); 2936 xmlFree(localname); 2937 if ( prefix != NULL ) { 2938 xmlFree(prefix); 2939 } 2940 xmlFree(ename); 2941 XSRETURN_UNDEF; 2942 } 2943 2944 xmlFree(localname); 2945 } 2946 else { 2947 xs_warn( " ordinary element " ); 2948 /* ordinary element */ 2949 localname = ename; 2950 2951 newNode = xmlNewDocNode( self, NULL , localname, NULL ); 2952 } 2953 2954 xmlSetNs(newNode, ns); 2955 docfrag = PmmNewFragment( self ); 2956 xmlAddChild(PmmNODE(docfrag), newNode); 2957 RETVAL = PmmNodeToSv(newNode, docfrag); 2958 2959 if ( prefix != NULL ) { 2960 xmlFree(prefix); 2961 } 2962 if ( eURI != NULL ) { 2963 xmlFree(eURI); 2964 } 2965 xmlFree(ename); 2966 OUTPUT: 2967 RETVAL 2968 2969SV * 2970createTextNode( self, content ) 2971 xmlDocPtr self 2972 SV * content 2973 PREINIT: 2974 xmlNodePtr newNode; 2975 xmlChar * elname = NULL; 2976 ProxyNodePtr docfrag = NULL; 2977 CODE: 2978 elname = nodeSv2C( content , (xmlNodePtr) self ); 2979 if ( elname != NULL || xmlStrlen(elname) > 0 ) { 2980 newNode = xmlNewDocText( self, elname ); 2981 xmlFree(elname); 2982 if ( newNode != NULL ) { 2983 docfrag = PmmNewFragment( self ); 2984 newNode->doc = self; 2985 xmlAddChild(PmmNODE(docfrag), newNode); 2986 RETVAL = PmmNodeToSv(newNode,docfrag); 2987 } 2988 else { 2989 xs_warn( "no node created!" ); 2990 XSRETURN_UNDEF; 2991 } 2992 } 2993 else { 2994 XSRETURN_UNDEF; 2995 } 2996 OUTPUT: 2997 RETVAL 2998 2999SV * 3000createComment( self , content ) 3001 xmlDocPtr self 3002 SV * content 3003 PREINIT: 3004 xmlNodePtr newNode; 3005 xmlChar * elname = NULL; 3006 ProxyNodePtr docfrag = NULL; 3007 CODE: 3008 elname = nodeSv2C( content , (xmlNodePtr) self ); 3009 if ( elname != NULL || xmlStrlen(elname) > 0 ) { 3010 newNode = xmlNewDocComment( self, elname ); 3011 xmlFree(elname); 3012 if ( newNode != NULL ) { 3013 docfrag = PmmNewFragment( self ); 3014 newNode->doc = self; 3015 xmlAddChild(PmmNODE(docfrag), newNode); 3016 xs_warn( newNode->name ); 3017 RETVAL = PmmNodeToSv(newNode,docfrag); 3018 } 3019 else { 3020 xs_warn( "no node created!" ); 3021 XSRETURN_UNDEF; 3022 } 3023 } 3024 else { 3025 XSRETURN_UNDEF; 3026 } 3027 OUTPUT: 3028 RETVAL 3029 3030SV * 3031createCDATASection( self, content ) 3032 xmlDocPtr self 3033 SV * content 3034 PREINIT: 3035 xmlNodePtr newNode; 3036 xmlChar * elname = NULL; 3037 ProxyNodePtr docfrag = NULL; 3038 CODE: 3039 elname = nodeSv2C( content , (xmlNodePtr)self ); 3040 if ( elname != NULL || xmlStrlen(elname) > 0 ) { 3041 newNode = xmlNewCDataBlock( self, elname, xmlStrlen(elname) ); 3042 xmlFree(elname); 3043 if ( newNode != NULL ) { 3044 docfrag = PmmNewFragment( self ); 3045 newNode->doc = self; 3046 xmlAddChild(PmmNODE(docfrag), newNode); 3047 xs_warn( "[CDATA section]" ); 3048 RETVAL = PmmNodeToSv(newNode,docfrag); 3049 } 3050 else { 3051 xs_warn( "no node created!" ); 3052 XSRETURN_UNDEF; 3053 } 3054 } 3055 else { 3056 XSRETURN_UNDEF; 3057 } 3058 OUTPUT: 3059 RETVAL 3060 3061SV* 3062createEntityReference( self , pname ) 3063 xmlDocPtr self 3064 SV * pname 3065 PREINIT: 3066 xmlNodePtr newNode; 3067 xmlChar * name = Sv2C( pname, NULL ); 3068 ProxyNodePtr docfrag = NULL; 3069 CODE: 3070 if ( name == NULL ) { 3071 XSRETURN_UNDEF; 3072 } 3073 newNode = xmlNewReference( self, name ); 3074 xmlFree(name); 3075 if ( newNode == NULL ) { 3076 XSRETURN_UNDEF; 3077 } 3078 docfrag = PmmNewFragment( self ); 3079 xmlAddChild(PmmNODE(docfrag), newNode); 3080 RETVAL = PmmNodeToSv( newNode, docfrag ); 3081 OUTPUT: 3082 RETVAL 3083 3084SV* 3085createAttribute( self, pname, pvalue=&PL_sv_undef ) 3086 xmlDocPtr self 3087 SV * pname 3088 SV * pvalue 3089 PREINIT: 3090 xmlChar * name = NULL; 3091 xmlChar * value = NULL; 3092 xmlAttrPtr newAttr = NULL; 3093 CODE: 3094 name = nodeSv2C( pname , (xmlNodePtr) self ); 3095 if ( !LibXML_test_node_name( name ) ) { 3096 xmlFree(name); 3097 XSRETURN_UNDEF; 3098 } 3099 3100 value = nodeSv2C( pvalue , (xmlNodePtr) self ); 3101 newAttr = xmlNewDocProp( self, name, value ); 3102 RETVAL = PmmNodeToSv((xmlNodePtr)newAttr, PmmPROXYNODE(self)); 3103 3104 xmlFree(name); 3105 if ( value ) { 3106 xmlFree(value); 3107 } 3108 OUTPUT: 3109 RETVAL 3110 3111SV* 3112createAttributeNS( self, URI, pname, pvalue=&PL_sv_undef ) 3113 xmlDocPtr self 3114 SV * URI 3115 SV * pname 3116 SV * pvalue 3117 PREINIT: 3118 xmlChar * name = NULL; 3119 xmlChar * value = NULL; 3120 xmlChar * prefix = NULL; 3121 const xmlChar * pchar = NULL; 3122 xmlChar * localname = NULL; 3123 xmlChar * nsURI = NULL; 3124 xmlAttrPtr newAttr = NULL; 3125 xmlNsPtr ns = NULL; 3126 CODE: 3127 name = nodeSv2C( pname , (xmlNodePtr) self ); 3128 if ( !LibXML_test_node_name( name ) ) { 3129 xmlFree(name); 3130 XSRETURN_UNDEF; 3131 } 3132 3133 nsURI = Sv2C( URI , NULL ); 3134 value = nodeSv2C( pvalue, (xmlNodePtr) self ); 3135 3136 if ( nsURI != NULL && xmlStrlen(nsURI) > 0 ) { 3137 xmlNodePtr root = xmlDocGetRootElement(self ); 3138 if ( root ) { 3139 pchar = xmlStrchr(name, ':'); 3140 if ( pchar != NULL ) { 3141 localname = xmlSplitQName2(name, &prefix); 3142 } 3143 else { 3144 localname = xmlStrdup( name ); 3145 } 3146 ns = xmlSearchNsByHref( self, root, nsURI ); 3147 if ( ns == NULL ) { 3148 /* create a new NS if the NS does not already exists */ 3149 ns = xmlNewNs(root, nsURI , prefix ); 3150 } 3151 3152 if ( ns == NULL ) { 3153 xmlFree(nsURI); 3154 xmlFree(localname); 3155 if ( prefix ) { 3156 xmlFree(prefix); 3157 } 3158 xmlFree(name); 3159 if ( value ) { 3160 xmlFree(value); 3161 } 3162 XSRETURN_UNDEF; 3163 } 3164 3165 newAttr = xmlNewDocProp( self, localname, value ); 3166 xmlSetNs((xmlNodePtr)newAttr, ns); 3167 3168 RETVAL = PmmNodeToSv((xmlNodePtr)newAttr, PmmPROXYNODE(self) ); 3169 3170 xmlFree(nsURI); 3171 xmlFree(name); 3172 if ( prefix ) { 3173 xmlFree(prefix); 3174 } 3175 xmlFree(localname); 3176 if ( value ) { 3177 xmlFree(value); 3178 } 3179 } 3180 else { 3181 croak( "can't create a new namespace on an attribute!" ); 3182 xmlFree(name); 3183 if ( value ) { 3184 xmlFree(value); 3185 } 3186 XSRETURN_UNDEF; 3187 } 3188 } 3189 else { 3190 newAttr = xmlNewDocProp( self, name, value ); 3191 RETVAL = PmmNodeToSv((xmlNodePtr)newAttr,PmmPROXYNODE(self)); 3192 xmlFree(name); 3193 if ( value ) { 3194 xmlFree(value); 3195 } 3196 } 3197 OUTPUT: 3198 RETVAL 3199 3200SV* 3201createProcessingInstruction(self, name, value=&PL_sv_undef) 3202 xmlDocPtr self 3203 SV * name 3204 SV * value 3205 ALIAS: 3206 createPI = 1 3207 PREINIT: 3208 xmlChar * n = NULL; 3209 xmlChar * v = NULL; 3210 xmlNodePtr newNode = NULL; 3211 ProxyNodePtr docfrag = NULL; 3212 CODE: 3213 n = nodeSv2C(name, (xmlNodePtr)self); 3214 if ( !n ) { 3215 XSRETURN_UNDEF; 3216 } 3217 v = nodeSv2C(value, (xmlNodePtr)self); 3218 newNode = xmlNewPI(n,v); 3219 xmlFree(v); 3220 xmlFree(n); 3221 if ( newNode != NULL ) { 3222 docfrag = PmmNewFragment( self ); 3223 newNode->doc = self; 3224 xmlAddChild(PmmNODE(docfrag), newNode); 3225 RETVAL = PmmNodeToSv(newNode,docfrag); 3226 } else { 3227 xs_warn( "no node created!" ); 3228 XSRETURN_UNDEF; 3229 } 3230 OUTPUT: 3231 RETVAL 3232 3233void 3234_setDocumentElement( self , proxy ) 3235 xmlDocPtr self 3236 SV * proxy 3237 PREINIT: 3238 xmlNodePtr elem, oelem; 3239 INIT: 3240 elem = PmmSvNode(proxy); 3241 if ( elem == NULL ) { 3242 XSRETURN_UNDEF; 3243 } 3244 CODE: 3245 /* please correct me if i am wrong: the document element HAS to be 3246 * an ELEMENT NODE 3247 */ 3248 if ( elem->type == XML_ELEMENT_NODE ) { 3249 if ( self != elem->doc ) { 3250 domImportNode( self, elem, 1, 1 ); 3251 } 3252 3253 oelem = xmlDocGetRootElement( self ); 3254 if ( oelem == NULL || oelem->_private == NULL ) { 3255 xmlDocSetRootElement( self, elem ); 3256 } 3257 else { 3258 ProxyNodePtr docfrag = PmmNewFragment( self ); 3259 xmlReplaceNode( oelem, elem ); 3260 xmlAddChild( PmmNODE(docfrag), oelem ); 3261 PmmFixOwner( ((ProxyNodePtr)oelem->_private), docfrag); 3262 } 3263 3264 if ( elem->_private != NULL ) { 3265 PmmFixOwner( SvPROXYNODE(proxy), PmmPROXYNODE(self)); 3266 } 3267 } 3268 3269SV * 3270documentElement( self ) 3271 xmlDocPtr self 3272 ALIAS: 3273 XML::LibXML::Document::getDocumentElement = 1 3274 PREINIT: 3275 xmlNodePtr elem; 3276 CODE: 3277 elem = xmlDocGetRootElement( self ); 3278 if ( elem ) { 3279 RETVAL = PmmNodeToSv(elem, PmmPROXYNODE(self)); 3280 } 3281 else { 3282 XSRETURN_UNDEF; 3283 } 3284 OUTPUT: 3285 RETVAL 3286 3287SV * 3288externalSubset( self ) 3289 xmlDocPtr self 3290 PREINIT: 3291 xmlDtdPtr dtd; 3292 CODE: 3293 if ( self->extSubset == NULL ) { 3294 XSRETURN_UNDEF; 3295 } 3296 3297 dtd = self->extSubset; 3298 RETVAL = PmmNodeToSv((xmlNodePtr)dtd, PmmPROXYNODE(self)); 3299 OUTPUT: 3300 RETVAL 3301 3302SV * 3303internalSubset( self ) 3304 xmlDocPtr self 3305 PREINIT: 3306 xmlDtdPtr dtd; 3307 CODE: 3308 if ( self->intSubset == NULL ) { 3309 XSRETURN_UNDEF; 3310 } 3311 3312 dtd = self->intSubset; 3313 RETVAL = PmmNodeToSv((xmlNodePtr)dtd, PmmPROXYNODE(self)); 3314 OUTPUT: 3315 RETVAL 3316 3317void 3318setExternalSubset( self, extdtd ) 3319 xmlDocPtr self 3320 SV * extdtd 3321 PREINIT: 3322 xmlDtdPtr dtd = NULL; 3323 xmlDtdPtr olddtd = NULL; 3324 INIT: 3325 dtd = (xmlDtdPtr)PmmSvNode(extdtd); 3326 if ( dtd == NULL ) { 3327 croak( "lost DTD node" ); 3328 } 3329 CODE: 3330 if ( dtd && dtd != self->extSubset ) { 3331 if ( dtd->doc == NULL ) { 3332 xmlSetTreeDoc( (xmlNodePtr) dtd, self ); 3333 } else if ( dtd->doc != self ) { 3334 domImportNode( self, (xmlNodePtr) dtd,1,1); 3335 } 3336 3337 if ( dtd == self->intSubset ) { 3338 xmlUnlinkNode( (xmlNodePtr)dtd ); 3339 self->intSubset = NULL; 3340 } 3341 3342 olddtd = self->extSubset; 3343 if ( olddtd && olddtd->_private == NULL ) { 3344 xmlFreeDtd( olddtd ); 3345 } 3346 self->extSubset = dtd; 3347 } 3348 3349void 3350setInternalSubset( self, extdtd ) 3351 xmlDocPtr self 3352 SV * extdtd 3353 PREINIT: 3354 xmlDtdPtr dtd = NULL; 3355 xmlDtdPtr olddtd = NULL; 3356 INIT: 3357 dtd = (xmlDtdPtr)PmmSvNode(extdtd); 3358 if ( dtd == NULL ) { 3359 croak( "lost DTD node" ); 3360 } 3361 CODE: 3362 if ( dtd && dtd != self->intSubset ) { 3363 if ( dtd->doc != self ) { 3364 croak( "can't import DTDs" ); 3365 domImportNode( self, (xmlNodePtr) dtd,1,1); 3366 } 3367 3368 if ( dtd == self->extSubset ) { 3369 self->extSubset = NULL; 3370 } 3371 3372 olddtd = xmlGetIntSubset( self ); 3373 if( olddtd ) { 3374 xmlReplaceNode( (xmlNodePtr)olddtd, (xmlNodePtr) dtd ); 3375 if ( olddtd->_private == NULL ) { 3376 xmlFreeDtd( olddtd ); 3377 } 3378 } 3379 else { 3380 if (self->children == NULL) 3381 xmlAddChild((xmlNodePtr) self, (xmlNodePtr) dtd); 3382 else 3383 xmlAddPrevSibling(self->children, (xmlNodePtr) dtd); 3384 } 3385 self->intSubset = dtd; 3386 } 3387 3388SV * 3389removeInternalSubset( self ) 3390 xmlDocPtr self 3391 PREINIT: 3392 xmlDtdPtr dtd = NULL; 3393 CODE: 3394 dtd = xmlGetIntSubset(self); 3395 if ( !dtd ) { 3396 XSRETURN_UNDEF; 3397 } 3398 xmlUnlinkNode( (xmlNodePtr)dtd ); 3399 self->intSubset = NULL; 3400 RETVAL = PmmNodeToSv( (xmlNodePtr)dtd, PmmPROXYNODE(self) ); 3401 OUTPUT: 3402 RETVAL 3403 3404SV * 3405removeExternalSubset( self ) 3406 xmlDocPtr self 3407 PREINIT: 3408 xmlDtdPtr dtd = NULL; 3409 CODE: 3410 dtd = self->extSubset; 3411 if ( !dtd ) { 3412 XSRETURN_UNDEF; 3413 } 3414 self->extSubset = NULL; 3415 RETVAL = PmmNodeToSv( (xmlNodePtr)dtd, PmmPROXYNODE(self) ); 3416 OUTPUT: 3417 RETVAL 3418 3419SV * 3420importNode( self, node, dummy=0 ) 3421 xmlDocPtr self 3422 xmlNodePtr node 3423 int dummy 3424 PREINIT: 3425 xmlNodePtr ret = NULL; 3426 ProxyNodePtr docfrag = NULL; 3427 CODE: 3428 if ( node->type == XML_DOCUMENT_NODE 3429 || node->type == XML_HTML_DOCUMENT_NODE ) { 3430 croak( "Can't import Documents!" ); 3431 XSRETURN_UNDEF; 3432 } 3433 3434 ret = domImportNode( self, node, 0, 1 ); 3435 if ( ret ) { 3436 docfrag = PmmNewFragment( self ); 3437 xmlAddChild( PmmNODE(docfrag), ret ); 3438 RETVAL = PmmNodeToSv( ret, docfrag); 3439 } 3440 else { 3441 XSRETURN_UNDEF; 3442 } 3443 OUTPUT: 3444 RETVAL 3445 3446SV * 3447adoptNode( self, node ) 3448 xmlDocPtr self 3449 xmlNodePtr node 3450 PREINIT: 3451 xmlNodePtr ret = NULL; 3452 ProxyNodePtr docfrag = NULL; 3453 CODE: 3454 if ( node->type == XML_DOCUMENT_NODE 3455 || node->type == XML_HTML_DOCUMENT_NODE ) { 3456 croak( "Can't adopt Documents!" ); 3457 XSRETURN_UNDEF; 3458 } 3459 3460 ret = domImportNode( self, node, 1, 1 ); 3461 3462 if ( ret ) { 3463 docfrag = PmmNewFragment( self ); 3464 RETVAL = PmmNodeToSv(node, docfrag); 3465 xmlAddChild( PmmNODE(docfrag), ret ); 3466 PmmFixOwner(SvPROXYNODE(RETVAL), docfrag); 3467 } 3468 else { 3469 XSRETURN_UNDEF; 3470 } 3471 OUTPUT: 3472 RETVAL 3473 3474char* 3475encoding( self ) 3476 xmlDocPtr self 3477 ALIAS: 3478 XML::LibXML::Document::getEncoding = 1 3479 XML::LibXML::Document::xmlEncoding = 2 3480 CODE: 3481 RETVAL = (char *) self->encoding; 3482 OUTPUT: 3483 RETVAL 3484 3485void 3486setEncoding( self, encoding ) 3487 xmlDocPtr self 3488 char *encoding 3489 PREINIT: 3490 int charset = XML_CHAR_ENCODING_ERROR; 3491 CODE: 3492 if ( self->encoding != NULL ) { 3493 xmlFree( (xmlChar*) self->encoding ); 3494 } 3495 self->encoding = xmlStrdup( (const xmlChar *)encoding ); 3496 charset = (int)xmlParseCharEncoding( (const char*)self->encoding ); 3497 if ( charset > 0 ) { 3498 ((ProxyNodePtr)self->_private)->encoding = charset; 3499 } 3500 else { 3501 ((ProxyNodePtr)self->_private)->encoding = XML_CHAR_ENCODING_ERROR; 3502 } 3503 3504 3505int 3506standalone( self ) 3507 xmlDocPtr self 3508 ALIAS: 3509 XML::LibXML::Document::xmlStandalone = 1 3510 CODE: 3511 RETVAL = self->standalone; 3512 OUTPUT: 3513 RETVAL 3514 3515void 3516setStandalone( self, value = 0 ) 3517 xmlDocPtr self 3518 int value 3519 CODE: 3520 if ( value > 0 ) { 3521 self->standalone = 1; 3522 } 3523 else if ( value < 0 ) { 3524 self->standalone = -1; 3525 } 3526 else { 3527 self->standalone = 0; 3528 } 3529 3530char* 3531version( self ) 3532 xmlDocPtr self 3533 ALIAS: 3534 XML::LibXML::Document::getVersion = 1 3535 XML::LibXML::Document::xmlVersion = 2 3536 CODE: 3537 RETVAL = (char *) self->version; 3538 OUTPUT: 3539 RETVAL 3540 3541void 3542setVersion( self, version ) 3543 xmlDocPtr self 3544 char *version 3545 CODE: 3546 if ( self->version != NULL ) { 3547 xmlFree( (xmlChar*) self->version ); 3548 } 3549 self->version = xmlStrdup( (const xmlChar*)version ); 3550 3551int 3552compression( self ) 3553 xmlDocPtr self 3554 CODE: 3555 RETVAL = xmlGetDocCompressMode(self); 3556 OUTPUT: 3557 RETVAL 3558 3559void 3560setCompression( self, zLevel ) 3561 xmlDocPtr self 3562 int zLevel 3563 CODE: 3564 xmlSetDocCompressMode(self, zLevel); 3565 3566 3567int 3568is_valid(self, ...) 3569 xmlDocPtr self 3570 PREINIT: 3571 SV * saved_error = sv_2mortal(newSVpv("",0)); 3572 xmlValidCtxt cvp; 3573 xmlDtdPtr dtd = NULL; 3574 SV * dtd_sv; 3575 CODE: 3576 LibXML_init_error_ctx(saved_error); 3577 3578 cvp.userData = saved_error; 3579 cvp.error = (xmlValidityErrorFunc)LibXML_validity_error_ctx; 3580 cvp.warning = (xmlValidityWarningFunc)LibXML_validity_warning_ctx; 3581 3582 /* we need to initialize the node stack, because perl might 3583 * already have messed it up. 3584 */ 3585 cvp.nodeNr = 0; 3586 cvp.nodeTab = NULL; 3587 cvp.vstateNr = 0; 3588 cvp.vstateTab = NULL; 3589 3590 if (items > 1) { 3591 dtd_sv = ST(1); 3592 if ( sv_isobject(dtd_sv) && (SvTYPE(SvRV(dtd_sv)) == SVt_PVMG) ) { 3593 dtd = (xmlDtdPtr)PmmSvNode(dtd_sv); 3594 } 3595 RETVAL = xmlValidateDtd(&cvp, self, dtd); 3596 } 3597 else { 3598 RETVAL = xmlValidateDocument(&cvp, self); 3599 } 3600 3601 /* LibXML_report_error_ctx(saved_error, 1); */ 3602 OUTPUT: 3603 RETVAL 3604 3605int 3606validate(self, ...) 3607 xmlDocPtr self 3608 PREINIT: 3609 SV * saved_error = sv_2mortal(newSVpv("",0)); 3610 xmlValidCtxt cvp; 3611 xmlDtdPtr dtd; 3612 SV * dtd_sv; 3613 CODE: 3614 LibXML_init_error_ctx(saved_error); 3615 3616 cvp.userData = saved_error; 3617 cvp.error = (xmlValidityErrorFunc)LibXML_validity_error_ctx; 3618 cvp.warning = (xmlValidityWarningFunc)LibXML_validity_warning_ctx; 3619 /* we need to initialize the node stack, because perl might 3620 * already have messed it up. 3621 */ 3622 cvp.nodeNr = 0; 3623 cvp.nodeTab = NULL; 3624 cvp.vstateNr = 0; 3625 cvp.vstateTab = NULL; 3626 3627 if (items > 1) { 3628 dtd_sv = ST(1); 3629 if ( sv_isobject(dtd_sv) && (SvTYPE(SvRV(dtd_sv)) == SVt_PVMG) ) { 3630 dtd = (xmlDtdPtr)PmmSvNode(dtd_sv); 3631 } 3632 else { 3633 croak("is_valid: argument must be a DTD object"); 3634 } 3635 RETVAL = xmlValidateDtd(&cvp, self , dtd); 3636 } 3637 else { 3638 RETVAL = xmlValidateDocument(&cvp, self); 3639 } 3640 3641 LibXML_report_error_ctx(saved_error, RETVAL ? 1 : 0); 3642 OUTPUT: 3643 RETVAL 3644 3645SV* 3646cloneNode( self, deep=0 ) 3647 xmlDocPtr self 3648 int deep 3649 PREINIT: 3650 xmlDocPtr ret = NULL; 3651 CODE: 3652 ret = xmlCopyDoc( self, deep ); 3653 if ( ret == NULL ) { 3654 XSRETURN_UNDEF; 3655 } 3656 RETVAL = PmmNodeToSv((xmlNodePtr)ret, NULL); 3657 OUTPUT: 3658 RETVAL 3659 3660SV* 3661getElementById( self, id ) 3662 xmlDocPtr self 3663 const char * id 3664 ALIAS: 3665 XML::LibXML::Document::getElementsById = 1 3666 PREINIT: 3667 xmlNodePtr elem; 3668 xmlAttrPtr attr; 3669 CODE: 3670 if ( id != NULL ) { 3671 attr = xmlGetID(self, (xmlChar *) id); 3672 if (attr == NULL) 3673 elem = NULL; 3674 else if (attr->type == XML_ATTRIBUTE_NODE) 3675 elem = attr->parent; 3676 else if (attr->type == XML_ELEMENT_NODE) 3677 elem = (xmlNodePtr) attr; 3678 else 3679 elem = NULL; 3680 if (elem != NULL) { 3681 RETVAL = PmmNodeToSv(elem, PmmPROXYNODE(self)); 3682 } 3683 else { 3684 XSRETURN_UNDEF; 3685 } 3686 } 3687 else { 3688 XSRETURN_UNDEF; 3689 } 3690 OUTPUT: 3691 RETVAL 3692 3693int 3694indexElements ( self ) 3695 xmlDocPtr self 3696 CODE: 3697#if LIBXML_VERSION >= 20508 3698 RETVAL = xmlXPathOrderDocElems( self ); 3699#else 3700 RETVAL = -2; 3701#endif 3702 OUTPUT: 3703 RETVAL 3704 3705MODULE = XML::LibXML PACKAGE = XML::LibXML::Node 3706 3707void 3708DESTROY( node ) 3709 SV * node 3710 CODE: 3711 xs_warn("DESTROY PERL NODE\n"); 3712 PmmREFCNT_dec(SvPROXYNODE(node)); 3713 3714SV* 3715nodeName( self ) 3716 xmlNodePtr self 3717 ALIAS: 3718 XML::LibXML::Node::getName = 1 3719 XML::LibXML::Element::tagName = 2 3720 PREINIT: 3721 xmlChar * name = NULL; 3722 CODE: 3723 name = (xmlChar*)domName( self ); 3724 if ( name != NULL ) { 3725 RETVAL = C2Sv(name,NULL); 3726 xmlFree( name ); 3727 } 3728 else { 3729 XSRETURN_UNDEF; 3730 } 3731 OUTPUT: 3732 RETVAL 3733 3734SV* 3735localname( self ) 3736 xmlNodePtr self 3737 ALIAS: 3738 XML::LibXML::Node::getLocalName = 1 3739 XML::LibXML::Attr::name = 2 3740 XML::LibXML::Node::localName = 3 3741 CODE: 3742 if ( self->type == XML_ELEMENT_NODE 3743 || self->type == XML_ATTRIBUTE_NODE 3744 || self->type == XML_ELEMENT_DECL 3745 || self->type == XML_ATTRIBUTE_DECL ) { 3746 RETVAL = C2Sv(self->name,NULL); 3747 } 3748 else { 3749 XSRETURN_UNDEF; 3750 } 3751 OUTPUT: 3752 RETVAL 3753 3754SV* 3755prefix( self ) 3756 xmlNodePtr self 3757 ALIAS: 3758 XML::LibXML::Node::getPrefix = 1 3759 CODE: 3760 if( self->ns != NULL 3761 && self->ns->prefix != NULL ) { 3762 RETVAL = C2Sv(self->ns->prefix, NULL); 3763 } 3764 else { 3765 XSRETURN_UNDEF; 3766 } 3767 OUTPUT: 3768 RETVAL 3769 3770SV* 3771namespaceURI( self ) 3772 xmlNodePtr self 3773 ALIAS: 3774 getNamespaceURI = 1 3775 PREINIT: 3776 xmlChar * nsURI; 3777 CODE: 3778 if ( self->ns != NULL 3779 && self->ns->href != NULL ) { 3780 nsURI = xmlStrdup(self->ns->href); 3781 RETVAL = C2Sv( nsURI, NULL ); 3782 xmlFree( nsURI ); 3783 } 3784 else { 3785 XSRETURN_UNDEF; 3786 } 3787 OUTPUT: 3788 RETVAL 3789 3790 3791SV* 3792lookupNamespaceURI( self, svprefix=&PL_sv_undef ) 3793 xmlNodePtr self 3794 SV * svprefix 3795 PREINIT: 3796 xmlChar * nsURI; 3797 xmlChar * prefix = NULL; 3798 xmlNsPtr ns; 3799 CODE: 3800 prefix = nodeSv2C( svprefix , self ); 3801 if ( prefix != NULL && xmlStrlen(prefix) == 0) { 3802 xmlFree( prefix ); 3803 prefix = NULL; 3804 } 3805 ns = xmlSearchNs( self->doc, self, prefix ); 3806 if ( prefix != NULL) { 3807 xmlFree( prefix ); 3808 } 3809 if ( ns != NULL ) { 3810 nsURI = xmlStrdup(ns->href); 3811 RETVAL = C2Sv( nsURI, NULL ); 3812 xmlFree( nsURI ); 3813 } 3814 else { 3815 XSRETURN_UNDEF; 3816 } 3817 OUTPUT: 3818 RETVAL 3819 3820SV* 3821lookupNamespacePrefix( self, svuri ) 3822 xmlNodePtr self 3823 SV * svuri 3824 PREINIT: 3825 xmlChar * nsprefix; 3826 xmlChar * href = NULL; 3827 CODE: 3828 href = nodeSv2C( svuri , self ); 3829 if ( href != NULL && xmlStrlen(href) > 0) { 3830 xmlNsPtr ns = xmlSearchNsByHref( self->doc, self, href ); 3831 xmlFree( href ); 3832 if ( ns != NULL ) { 3833 if ( ns->prefix != NULL ) { 3834 nsprefix = xmlStrdup( ns->prefix ); 3835 RETVAL = C2Sv( nsprefix, NULL ); 3836 xmlFree(nsprefix); 3837 } else { 3838 RETVAL = newSVpv("",0); 3839 } 3840 } 3841 else { 3842 XSRETURN_UNDEF; 3843 } 3844 } 3845 else { 3846 XSRETURN_UNDEF; 3847 } 3848 OUTPUT: 3849 RETVAL 3850 3851int 3852setNamespaceDeclURI( self, svprefix, newURI ) 3853 xmlNodePtr self 3854 SV * svprefix 3855 SV * newURI 3856 PREINIT: 3857 xmlChar * prefix = NULL; 3858 xmlChar * nsURI = NULL; 3859 xmlNsPtr ns; 3860 CODE: 3861 prefix = nodeSv2C( svprefix , self ); 3862 nsURI = nodeSv2C( newURI , self ); 3863 /* null empty values */ 3864 if ( prefix && xmlStrlen(prefix) == 0) { 3865 xmlFree( prefix ); 3866 prefix = NULL; 3867 } 3868 if ( nsURI && xmlStrlen(nsURI) == 0) { 3869 xmlFree( nsURI ); 3870 nsURI = NULL; 3871 } 3872 RETVAL = 0; 3873 ns = self->nsDef; 3874 while ( ns ) { 3875 if ((ns->prefix || ns->href ) && 3876 ( xmlStrcmp( ns->prefix, prefix ) == 0 )) { 3877 if (ns->href) xmlFree((char*)ns->href); 3878 ns->href = nsURI; 3879 if ( nsURI == NULL ) { 3880 domRemoveNsRefs( self, ns ); 3881 } else 3882 nsURI = NULL; /* do not free it */ 3883 RETVAL = 1; 3884 break; 3885 } else { 3886 ns = ns->next; 3887 } 3888 } 3889 if ( prefix ) xmlFree( prefix ); 3890 if ( nsURI ) xmlFree( nsURI ); 3891 OUTPUT: 3892 RETVAL 3893 3894int 3895setNamespaceDeclPrefix( self, svprefix, newPrefix ) 3896 xmlNodePtr self 3897 SV * svprefix 3898 SV * newPrefix 3899 PREINIT: 3900 xmlChar * prefix = NULL; 3901 xmlChar * nsPrefix = NULL; 3902 xmlNsPtr ns; 3903 CODE: 3904 prefix = nodeSv2C( svprefix , self ); 3905 nsPrefix = nodeSv2C( newPrefix , self ); 3906 /* null empty values */ 3907 if ( prefix != NULL && xmlStrlen(prefix) == 0) { 3908 xmlFree( prefix ); 3909 prefix = NULL; 3910 } 3911 if ( nsPrefix != NULL && xmlStrlen(nsPrefix) == 0) { 3912 xmlFree( nsPrefix ); 3913 nsPrefix = NULL; 3914 } 3915 if ( xmlStrcmp( prefix, nsPrefix ) == 0 ) { 3916 RETVAL = 1; 3917 } else { 3918 RETVAL = 0; 3919 /* check that new prefix is not in scope */ 3920 ns = xmlSearchNs( self->doc, self, nsPrefix ); 3921 if ( ns != NULL ) { 3922 if (nsPrefix != NULL) xmlFree( nsPrefix ); 3923 if (prefix != NULL) xmlFree( prefix ); 3924 croak("setNamespaceDeclPrefix: prefix '%s' is in use", ns->prefix); 3925 } 3926 /* lookup the declaration */ 3927 ns = self->nsDef; 3928 while ( ns != NULL ) { 3929 if ((ns->prefix != NULL || ns->href != NULL) && 3930 xmlStrcmp( ns->prefix, prefix ) == 0 ) { 3931 if ( ns->href == NULL && nsPrefix != NULL ) { 3932 /* xmlns:foo="" - no go */ 3933 if ( prefix != NULL) xmlFree(prefix); 3934 croak("setNamespaceDeclPrefix: cannot set non-empty prefix for empty namespace"); 3935 } 3936 if ( ns->prefix != NULL ) xmlFree( (xmlChar*)ns->prefix ); 3937 ns->prefix = nsPrefix; 3938 nsPrefix = NULL; /* do not free it */ 3939 RETVAL = 1; 3940 break; 3941 } else { 3942 ns = ns->next; 3943 } 3944 } 3945 } 3946 if ( nsPrefix != NULL ) xmlFree(nsPrefix); 3947 if ( prefix != NULL) xmlFree(prefix); 3948 OUTPUT: 3949 RETVAL 3950 3951void 3952setNodeName( self , value ) 3953 xmlNodePtr self 3954 SV* value 3955 ALIAS: 3956 setName = 1 3957 PREINIT: 3958 xmlChar* string; 3959 xmlChar* localname; 3960 xmlChar* prefix; 3961 CODE: 3962 string = nodeSv2C( value , self ); 3963 if ( !LibXML_test_node_name( string ) ) { 3964 xmlFree(string); 3965 croak( "bad name" ); 3966 } 3967 if( self->ns ){ 3968 localname = xmlSplitQName2(string, &prefix); 3969 if ( localname == NULL ) { 3970 localname = xmlStrdup( string ); 3971 } 3972 xmlNodeSetName(self, localname ); 3973 xmlFree(localname); 3974 xmlFree(prefix); 3975 } 3976 else { 3977 xs_warn("node name normal\n"); 3978 xmlNodeSetName(self, string ); 3979 } 3980 xmlFree(string); 3981 3982void 3983setRawName( self, value ) 3984 xmlNodePtr self 3985 SV * value 3986 PREINIT: 3987 xmlChar* string; 3988 xmlChar* localname; 3989 xmlChar* prefix; 3990 CODE: 3991 string = nodeSv2C( value , self ); 3992 if ( !string || xmlStrlen( string) <= 0 ) { 3993 xmlFree(string); 3994 XSRETURN_UNDEF; 3995 } 3996 if( self->ns ){ 3997 localname = xmlSplitQName2(string, &prefix); 3998 xmlNodeSetName(self, localname ); 3999 xmlFree(localname); 4000 xmlFree(prefix); 4001 } 4002 else { 4003 xmlNodeSetName(self, string ); 4004 } 4005 xmlFree(string); 4006 4007 4008SV* 4009nodeValue( self, useDomEncoding = &PL_sv_undef ) 4010 xmlNodePtr self 4011 SV * useDomEncoding 4012 ALIAS: 4013 XML::LibXML::Attr::value = 1 4014 XML::LibXML::Attr::getValue = 2 4015 XML::LibXML::Text::data = 3 4016 XML::LibXML::Node::getValue = 4 4017 XML::LibXML::Node::getData = 5 4018 PREINIT: 4019 xmlChar * content = NULL; 4020 CODE: 4021 content = domGetNodeValue( self ); 4022 4023 if ( content != NULL ) { 4024 if ( SvTRUE(useDomEncoding) ) { 4025 RETVAL = nodeC2Sv(content, self); 4026 } 4027 else { 4028 RETVAL = C2Sv(content, NULL); 4029 } 4030 xmlFree(content); 4031 } 4032 else { 4033 XSRETURN_UNDEF; 4034 } 4035 OUTPUT: 4036 RETVAL 4037 4038int 4039nodeType( self ) 4040 xmlNodePtr self 4041 ALIAS: 4042 XML::LibXML::Node::getType = 1 4043 CODE: 4044 RETVAL = self->type; 4045 OUTPUT: 4046 RETVAL 4047 4048SV* 4049parentNode( self ) 4050 xmlNodePtr self 4051 ALIAS: 4052 XML::LibXML::Attr::ownerElement = 1 4053 XML::LibXML::Node::getParentNode = 2 4054 XML::LibXML::Attr::getOwnerElement = 3 4055 CODE: 4056 RETVAL = PmmNodeToSv( self->parent, 4057 PmmOWNERPO( PmmPROXYNODE(self) ) ); 4058 OUTPUT: 4059 RETVAL 4060 4061SV* 4062nextSibling( self ) 4063 xmlNodePtr self 4064 ALIAS: 4065 getNextSibling = 1 4066 CODE: 4067 RETVAL = PmmNodeToSv( self->next, 4068 PmmOWNERPO(PmmPROXYNODE(self)) ); 4069 OUTPUT: 4070 RETVAL 4071 4072SV* 4073previousSibling( self ) 4074 xmlNodePtr self 4075 ALIAS: 4076 getPreviousSibling = 1 4077 CODE: 4078 RETVAL = PmmNodeToSv( self->prev, 4079 PmmOWNERPO( PmmPROXYNODE(self) ) ); 4080 OUTPUT: 4081 RETVAL 4082 4083void 4084_childNodes( self ) 4085 xmlNodePtr self 4086 ALIAS: 4087 XML::LibXML::Node::getChildnodes = 1 4088 PREINIT: 4089 xmlNodePtr cld; 4090 SV * element; 4091 int len = 0; 4092 int wantarray = GIMME_V; 4093 PPCODE: 4094 if ( self->type != XML_ATTRIBUTE_NODE ) { 4095 cld = self->children; 4096 xs_warn("childnodes start"); 4097 while ( cld ) { 4098 if( wantarray != G_SCALAR ) { 4099 element = PmmNodeToSv(cld, PmmOWNERPO(PmmPROXYNODE(self)) ); 4100 XPUSHs(sv_2mortal(element)); 4101 } 4102 cld = cld->next; 4103 len++; 4104 } 4105 } 4106 if ( wantarray == G_SCALAR ) { 4107 XPUSHs(sv_2mortal(newSViv(len)) ); 4108 } 4109 4110void 4111_getChildrenByTagNameNS( self, namespaceURI, node_name ) 4112 xmlNodePtr self 4113 SV * namespaceURI 4114 SV * node_name 4115 PREINIT: 4116 xmlChar * name; 4117 xmlChar * nsURI; 4118 xmlNodePtr cld; 4119 SV * element; 4120 int len = 0; 4121 int name_wildcard = 0; 4122 int ns_wildcard = 0; 4123 int wantarray = GIMME_V; 4124 PPCODE: 4125 name = nodeSv2C(node_name, self ); 4126 nsURI = nodeSv2C(namespaceURI, self ); 4127 4128 if ( nsURI != NULL ) { 4129 if (xmlStrlen(nsURI) == 0 ) { 4130 xmlFree(nsURI); 4131 nsURI = NULL; 4132 } else if (xmlStrcmp( nsURI, (xmlChar *)"*" )==0) { 4133 ns_wildcard = 1; 4134 } 4135 } 4136 if ( name !=NULL && xmlStrcmp( name, (xmlChar *)"*" ) == 0) { 4137 name_wildcard = 1; 4138 } 4139 if ( self->type != XML_ATTRIBUTE_NODE ) { 4140 cld = self->children; 4141 xs_warn("childnodes start"); 4142 while ( cld ) { 4143 if (((name_wildcard && (cld->type == XML_ELEMENT_NODE)) || 4144 xmlStrcmp( name, cld->name ) == 0) 4145 && (ns_wildcard || 4146 (cld->ns != NULL && 4147 xmlStrcmp(nsURI,cld->ns->href) == 0 ) || 4148 (cld->ns == NULL && nsURI == NULL))) { 4149 if( wantarray != G_SCALAR ) { 4150 element = PmmNodeToSv(cld, PmmOWNERPO(PmmPROXYNODE(self)) ); 4151 XPUSHs(sv_2mortal(element)); 4152 } 4153 len++; 4154 } 4155 cld = cld->next; 4156 } 4157 } 4158 if ( wantarray == G_SCALAR ) { 4159 XPUSHs(sv_2mortal(newSViv(len)) ); 4160 } 4161 4162SV* 4163firstChild( self ) 4164 xmlNodePtr self 4165 ALIAS: 4166 getFirstChild = 1 4167 CODE: 4168 RETVAL = PmmNodeToSv( self->children, 4169 PmmOWNERPO( PmmPROXYNODE(self) ) ); 4170 OUTPUT: 4171 RETVAL 4172 4173SV* 4174lastChild( self ) 4175 xmlNodePtr self 4176 ALIAS: 4177 getLastChild = 1 4178 CODE: 4179 RETVAL = PmmNodeToSv( self->last, 4180 PmmOWNERPO( PmmPROXYNODE(self) ) ); 4181 OUTPUT: 4182 RETVAL 4183 4184void 4185_attributes( self ) 4186 xmlNodePtr self 4187 ALIAS: 4188 XML::LibXML::Node::getAttributes = 1 4189 PREINIT: 4190 xmlAttrPtr attr = NULL; 4191 xmlNsPtr ns = NULL; 4192 SV * element; 4193 int len=0; 4194 int wantarray = GIMME_V; 4195 PPCODE: 4196 if ( self->type != XML_ATTRIBUTE_NODE ) { 4197 attr = self->properties; 4198 while ( attr != NULL ) { 4199 if ( wantarray != G_SCALAR ) { 4200 element = PmmNodeToSv((xmlNodePtr)attr, 4201 PmmOWNERPO(PmmPROXYNODE(self)) ); 4202 XPUSHs(sv_2mortal(element)); 4203 } 4204 attr = attr->next; 4205 len++; 4206 } 4207 4208 ns = self->nsDef; 4209 while ( ns != NULL ) { 4210 const char * CLASS = "XML::LibXML::Namespace"; 4211 if ( wantarray != G_SCALAR ) { 4212 /* namespace handling is kinda odd: 4213 * as soon we have a namespace isolated from its 4214 * owner, we loose the context. therefore it is 4215 * forbidden to access the NS information directly. 4216 * instead the use will recieve a copy of the real 4217 * namespace, that can be destroied and is not 4218 * bound to a document. 4219 * 4220 * this avoids segfaults in the end. 4221 */ 4222 if ((ns->prefix != NULL || ns->href != NULL)) { 4223 xmlNsPtr tns = xmlCopyNamespace(ns); 4224 if ( tns != NULL ) { 4225 element = sv_newmortal(); 4226 XPUSHs(sv_setref_pv( element, 4227 (char *)CLASS, 4228 (void*)tns)); 4229 } 4230 } 4231 } 4232 ns = ns->next; 4233 len++; 4234 } 4235 } 4236 if( wantarray == G_SCALAR ) { 4237 XPUSHs( sv_2mortal(newSViv(len)) ); 4238 } 4239 4240int 4241hasChildNodes( self ) 4242 xmlNodePtr self 4243 CODE: 4244 if ( self->type == XML_ATTRIBUTE_NODE ) { 4245 RETVAL = 0; 4246 } 4247 else { 4248 RETVAL = self->children ? 1 : 0 ; 4249 } 4250 OUTPUT: 4251 RETVAL 4252 4253int 4254hasAttributes( self ) 4255 xmlNodePtr self 4256 CODE: 4257 if ( self->type == XML_ATTRIBUTE_NODE ) { 4258 RETVAL = 0; 4259 } 4260 else { 4261 RETVAL = self->properties ? 1 : 0 ; 4262 } 4263 OUTPUT: 4264 RETVAL 4265 4266SV* 4267ownerDocument( self ) 4268 xmlNodePtr self 4269 ALIAS: 4270 XML::LibXML::Node::getOwnerDocument = 1 4271 CODE: 4272 xs_warn( "GET OWNERDOC\n" ); 4273 if( self != NULL 4274 && self->doc != NULL ){ 4275 RETVAL = PmmNodeToSv((xmlNodePtr)(self->doc), NULL); 4276 } 4277 else { 4278 XSRETURN_UNDEF; 4279 } 4280 OUTPUT: 4281 RETVAL 4282 4283SV* 4284ownerNode( self ) 4285 xmlNodePtr self 4286 ALIAS: 4287 XML::LibXML::Node::getOwner = 1 4288 XML::LibXML::Node::getOwnerElement = 2 4289 CODE: 4290 RETVAL = PmmNodeToSv(PmmNODE(PmmOWNERPO(PmmPROXYNODE(self))), NULL); 4291 OUTPUT: 4292 RETVAL 4293 4294 4295int 4296normalize( self ) 4297 xmlNodePtr self 4298 CODE: 4299 RETVAL = domNodeNormalize( self ); 4300 OUTPUT: 4301 RETVAL 4302 4303 4304SV* 4305insertBefore( self, nNode, ref ) 4306 xmlNodePtr self 4307 xmlNodePtr nNode 4308 SV * ref 4309 PREINIT: 4310 xmlNodePtr oNode=NULL, rNode; 4311 INIT: 4312 oNode = PmmSvNode(ref); 4313 CODE: 4314 if ( self->type == XML_DOCUMENT_NODE 4315 && nNode->type == XML_ELEMENT_NODE ) { 4316 xs_warn( "NOT_SUPPORTED_ERR\n" ); 4317 XSRETURN_UNDEF; 4318 } 4319 else { 4320 rNode = domInsertBefore( self, nNode, oNode ); 4321 if ( rNode != NULL ) { 4322 RETVAL = PmmNodeToSv( rNode, 4323 PmmOWNERPO(PmmPROXYNODE(self)) ); 4324 PmmFixOwner(PmmOWNERPO(SvPROXYNODE(RETVAL)), 4325 PmmOWNERPO(PmmPROXYNODE(self)) ); 4326 } 4327 else { 4328 XSRETURN_UNDEF; 4329 } 4330 } 4331 OUTPUT: 4332 RETVAL 4333 4334SV* 4335insertAfter( self, nNode, ref ) 4336 xmlNodePtr self 4337 xmlNodePtr nNode 4338 SV* ref 4339 PREINIT: 4340 xmlNodePtr oNode = NULL, rNode; 4341 INIT: 4342 oNode = PmmSvNode(ref); 4343 CODE: 4344 if ( self->type == XML_DOCUMENT_NODE 4345 && nNode->type == XML_ELEMENT_NODE ) { 4346 xs_warn( "NOT_SUPPORTED_ERR\n" ); 4347 XSRETURN_UNDEF; 4348 } 4349 else { 4350 rNode = domInsertAfter( self, nNode, oNode ); 4351 if ( rNode != NULL ) { 4352 RETVAL = PmmNodeToSv( rNode, 4353 PmmOWNERPO(PmmPROXYNODE(self)) ); 4354 PmmFixOwner(PmmOWNERPO(SvPROXYNODE(RETVAL)), 4355 PmmOWNERPO(PmmPROXYNODE(self)) ); 4356 } 4357 else { 4358 XSRETURN_UNDEF; 4359 } 4360 } 4361 OUTPUT: 4362 RETVAL 4363 4364SV* 4365replaceChild( self, nNode, oNode ) 4366 xmlNodePtr self 4367 xmlNodePtr nNode 4368 xmlNodePtr oNode 4369 PREINIT: 4370 xmlNodePtr ret = NULL; 4371 ProxyNodePtr docfrag = NULL; 4372 CODE: 4373 if ( self->type == XML_DOCUMENT_NODE ) { 4374 switch ( nNode->type ) { 4375 case XML_ELEMENT_NODE: 4376 case XML_DOCUMENT_FRAG_NODE: 4377 case XML_TEXT_NODE: 4378 case XML_CDATA_SECTION_NODE: 4379 XSRETURN_UNDEF; 4380 break; 4381 default: 4382 break; 4383 } 4384 } 4385 ret = domReplaceChild( self, nNode, oNode ); 4386 if (ret == NULL) { 4387 XSRETURN_UNDEF; 4388 } 4389 else { 4390 docfrag = PmmNewFragment( self->doc ); 4391 /* create document fragment */ 4392 xmlAddChild( PmmNODE(docfrag), ret ); 4393 RETVAL = PmmNodeToSv(ret, docfrag); 4394 4395 if ( nNode->_private != NULL ) { 4396 PmmFixOwner( PmmPROXYNODE(nNode), 4397 PmmOWNERPO(PmmPROXYNODE(self)) ); 4398 } 4399 PmmFixOwner( SvPROXYNODE(RETVAL), docfrag ); 4400 } 4401 OUTPUT: 4402 RETVAL 4403 4404SV* 4405replaceNode( self,nNode ) 4406 xmlNodePtr self 4407 xmlNodePtr nNode 4408 PREINIT: 4409 xmlNodePtr ret = NULL; 4410 ProxyNodePtr docfrag = NULL; 4411 CODE: 4412 if ( domIsParent( self, nNode ) == 1 ) { 4413 XSRETURN_UNDEF; 4414 } 4415 if ( self->doc != nNode->doc ) { 4416 domImportNode( self->doc, nNode, 1, 1 ); 4417 } 4418 4419 if ( self->type != XML_ATTRIBUTE_NODE ) { 4420 ret = domReplaceChild( self->parent, nNode, self); 4421 } 4422 else { 4423 ret = xmlReplaceNode( self, nNode ); 4424 } 4425 if ( ret ) { 4426 if ( ret->type == XML_ATTRIBUTE_NODE ) { 4427 docfrag = NULL; 4428 } 4429 else { 4430 /* create document fragment */ 4431 docfrag = PmmNewFragment( self->doc ); 4432 xmlAddChild( PmmNODE(docfrag), ret ); 4433 } 4434 4435 RETVAL = PmmNodeToSv(ret, docfrag); 4436 if ( nNode->_private != NULL ) { 4437 PmmFixOwner( PmmPROXYNODE(nNode), 4438 PmmOWNERPO(PmmPROXYNODE(self))); 4439 } 4440 PmmFixOwner( SvPROXYNODE(RETVAL), docfrag ); 4441 } 4442 else { 4443 croak( "replacement failed" ); 4444 XSRETURN_UNDEF; 4445 } 4446 OUTPUT: 4447 RETVAL 4448 4449SV* 4450removeChild( self, node ) 4451 xmlNodePtr self 4452 xmlNodePtr node 4453 PREINIT: 4454 xmlNodePtr ret; 4455 CODE: 4456 ret = domRemoveChild( self, node ); 4457 if (ret == NULL) { 4458 XSRETURN_UNDEF; 4459 } 4460 else { 4461 ProxyNodePtr docfrag = PmmNewFragment( ret->doc ); 4462 xmlAddChild( PmmNODE(docfrag), ret ); 4463 RETVAL = PmmNodeToSv(ret,NULL); 4464 PmmFixOwner( SvPROXYNODE(RETVAL), docfrag ); 4465 } 4466 OUTPUT: 4467 RETVAL 4468 4469void 4470removeChildNodes( self ) 4471 xmlNodePtr self 4472 PREINIT: 4473 xmlNodePtr elem, fragment; 4474 ProxyNodePtr docfrag; 4475 CODE: 4476 docfrag = PmmNewFragment( self->doc ); 4477 fragment = PmmNODE( docfrag ); 4478 elem = self->children; 4479 while ( elem ) { 4480 xmlUnlinkNode( elem ); 4481 /* this following piece is the function of domAppendChild() 4482 * but in this special case we can avoid most of the logic of 4483 * that function. 4484 */ 4485 if ( fragment->children != NULL ) { 4486 xs_warn("unlink node!\n"); 4487 domAddNodeToList( elem, fragment->last, NULL ); 4488 } 4489 else { 4490 fragment->children = elem; 4491 fragment->last = elem; 4492 elem->parent= fragment; 4493 } 4494 PmmFixOwnerNode( elem, docfrag ); 4495 elem = elem->next; 4496 } 4497 4498 self->children = self->last = NULL; 4499 if ( PmmREFCNT(docfrag) <= 0 ) { 4500 xs_warn( "have not references left" ); 4501 PmmREFCNT_inc( docfrag ); 4502 PmmREFCNT_dec( docfrag ); 4503 } 4504 4505void 4506unbindNode( self ) 4507 xmlNodePtr self 4508 ALIAS: 4509 XML::LibXML::Node::unlink = 1 4510 XML::LibXML::Node::unlinkNode = 2 4511 PREINIT: 4512 ProxyNodePtr docfrag = NULL; 4513 CODE: 4514 if ( self->type != XML_DOCUMENT_NODE 4515 || self->type != XML_DOCUMENT_FRAG_NODE ) { 4516 xmlUnlinkNode( self ); 4517 if ( self->type != XML_ATTRIBUTE_NODE ) { 4518 docfrag = PmmNewFragment( self->doc ); 4519 xmlAddChild( PmmNODE(docfrag), self ); 4520 } 4521 PmmFixOwner( PmmPROXYNODE(self), docfrag ); 4522 } 4523 4524SV* 4525appendChild( self, nNode ) 4526 xmlNodePtr self 4527 xmlNodePtr nNode 4528 PREINIT: 4529 xmlNodePtr rNode; 4530 CODE: 4531 if (self->type == XML_DOCUMENT_NODE ) { 4532 /* NOT_SUPPORTED_ERR 4533 */ 4534 switch ( nNode->type ) { 4535 case XML_ELEMENT_NODE: 4536 case XML_DOCUMENT_FRAG_NODE: 4537 case XML_TEXT_NODE: 4538 case XML_CDATA_SECTION_NODE: 4539 XSRETURN_UNDEF; 4540 break; 4541 default: 4542 break; 4543 } 4544 } 4545 4546 rNode = domAppendChild( self, nNode ); 4547 4548 if ( rNode == NULL ) { 4549 XSRETURN_UNDEF; 4550 } 4551 4552 RETVAL = PmmNodeToSv( nNode, 4553 PmmOWNERPO(PmmPROXYNODE(self)) ); 4554 PmmFixOwner( SvPROXYNODE(RETVAL), PmmPROXYNODE(self) ); 4555 OUTPUT: 4556 RETVAL 4557 4558SV* 4559addChild( self, nNode ) 4560 xmlNodePtr self 4561 xmlNodePtr nNode 4562 PREINIT: 4563 xmlNodePtr retval = NULL; 4564 ProxyNodePtr proxy; 4565 CODE: 4566 xmlUnlinkNode(nNode); 4567 proxy = PmmPROXYNODE(nNode); 4568 retval = xmlAddChild( self, nNode ); 4569 4570 if ( retval == NULL ) { 4571 croak( "ERROR!\n" ); 4572 } 4573 4574 if ( retval != nNode ) { 4575 xs_warn( "node was lost during operation\n" ); 4576 PmmNODE(proxy) = NULL; 4577 } 4578 4579 RETVAL = PmmNodeToSv( retval, 4580 PmmOWNERPO(PmmPROXYNODE(self)) ); 4581 if ( retval != self ) { 4582 PmmFixOwner( SvPROXYNODE(RETVAL), PmmPROXYNODE(self) ); 4583 } 4584 OUTPUT: 4585 RETVAL 4586 4587 4588SV* 4589addSibling( self, nNode ) 4590 xmlNodePtr self 4591 xmlNodePtr nNode 4592 PREINIT: 4593 xmlNodePtr ret = NULL; 4594 CODE: 4595 if ( nNode->type == XML_DOCUMENT_FRAG_NODE ) { 4596 XSRETURN_UNDEF; 4597 } 4598 4599 ret = xmlAddSibling( self, nNode ); 4600 4601 if ( ret ) { 4602 RETVAL = PmmNodeToSv(ret,NULL); 4603 PmmFixOwner( SvPROXYNODE(RETVAL), PmmOWNERPO(PmmPROXYNODE(self)) ); 4604 } 4605 else { 4606 XSRETURN_UNDEF; 4607 } 4608 OUTPUT: 4609 RETVAL 4610 4611SV* 4612cloneNode( self, deep=0 ) 4613 xmlNodePtr self 4614 int deep 4615 PREINIT: 4616 xmlNodePtr ret; 4617 xmlDocPtr doc = NULL; 4618 ProxyNodePtr docfrag = NULL; 4619 CODE: 4620 ret = PmmCloneNode( self, deep ); 4621 if ( ret == NULL ) { 4622 XSRETURN_UNDEF; 4623 } 4624 4625 if ( ret->type == XML_DTD_NODE ) { 4626 RETVAL = PmmNodeToSv(ret, NULL); 4627 } 4628 else { 4629 doc = self->doc; 4630 4631 if ( doc != NULL ) { 4632 xmlSetTreeDoc(ret, doc); 4633 } 4634 4635 docfrag = PmmNewFragment( doc ); 4636 xmlAddChild( PmmNODE(docfrag), ret ); 4637 RETVAL = PmmNodeToSv(ret, docfrag); 4638 } 4639 OUTPUT: 4640 RETVAL 4641 4642int 4643isSameNode( self, oNode ) 4644 xmlNodePtr self 4645 xmlNodePtr oNode 4646 ALIAS: 4647 XML::LibXML::Node::isEqual = 1 4648 CODE: 4649 RETVAL = ( self == oNode ) ? 1 : 0; 4650 OUTPUT: 4651 RETVAL 4652 4653SV * 4654baseURI( self ) 4655 xmlNodePtr self 4656 PREINIT: 4657 xmlChar * uri; 4658 CODE: 4659 uri = xmlNodeGetBase( self->doc, self ); 4660 RETVAL = C2Sv( uri, NULL ); 4661 xmlFree( uri ); 4662 OUTPUT: 4663 RETVAL 4664 4665void 4666setBaseURI( self, URI ) 4667 xmlNodePtr self 4668 SV * URI 4669 PREINIT: 4670 xmlChar * uri; 4671 CODE: 4672 uri = nodeSv2C( URI, self ); 4673 if ( uri != NULL ) { 4674 xmlNodeSetBase( self, uri ); 4675 } 4676 4677SV* 4678toString( self, format=0, useDomEncoding = &PL_sv_undef ) 4679 xmlNodePtr self 4680 SV * useDomEncoding 4681 int format 4682 ALIAS: 4683 XML::LibXML::Node::serialize = 1 4684 PREINIT: 4685 xmlBufferPtr buffer; 4686 const xmlChar *ret = NULL; 4687 SV* internalFlag = NULL; 4688 int oldTagFlag = xmlSaveNoEmptyTags; 4689 CODE: 4690 internalFlag = perl_get_sv("XML::LibXML::setTagCompression", 0); 4691 4692 if ( internalFlag ) { 4693 xmlSaveNoEmptyTags = SvTRUE(internalFlag); 4694 } 4695 buffer = xmlBufferCreate(); 4696 4697 if ( format <= 0 ) { 4698 xmlNodeDump( buffer, 4699 self->doc, 4700 self, 0, format); 4701 } 4702 else { 4703 int t_indent_var = xmlIndentTreeOutput; 4704 xmlIndentTreeOutput = 1; 4705 xmlNodeDump( buffer, 4706 self->doc, 4707 self, 0, format); 4708 xmlIndentTreeOutput = t_indent_var; 4709 } 4710 4711 ret = xmlBufferContent( buffer ); 4712 4713 xmlSaveNoEmptyTags = oldTagFlag; 4714 4715 if ( ret != NULL ) { 4716 if ( useDomEncoding != &PL_sv_undef && SvTRUE(useDomEncoding) ) { 4717 RETVAL = nodeC2Sv((xmlChar*)ret, PmmNODE(PmmPROXYNODE(self))) ; 4718 SvUTF8_off(RETVAL); 4719 } 4720 else { 4721 RETVAL = C2Sv((xmlChar*)ret, NULL) ; 4722 } 4723 xmlBufferFree( buffer ); 4724 } 4725 else { 4726 xmlBufferFree( buffer ); 4727 xs_warn("Failed to convert node to string"); 4728 XSRETURN_UNDEF; 4729 } 4730 OUTPUT: 4731 RETVAL 4732 4733 4734SV * 4735_toStringC14N(self, comments=0, xpath=&PL_sv_undef, exclusive=0, inc_prefix_list=NULL) 4736 xmlNodePtr self 4737 int comments 4738 SV * xpath 4739 int exclusive 4740 char** inc_prefix_list 4741 4742 PREINIT: 4743 SV * saved_error = sv_2mortal(newSVpv("",0)); 4744 xmlChar *result = NULL; 4745 xmlChar *nodepath = NULL; 4746 xmlXPathContextPtr child_ctxt = NULL; 4747 xmlXPathObjectPtr child_xpath = NULL; 4748 xmlNodeSetPtr nodelist = NULL; 4749 xmlNodePtr refNode = NULL; 4750 INIT: 4751 /* due to how c14n is implemented, the nodeset it receives must 4752 include child nodes; ie, child nodes aren't assumed to be rendered. 4753 so we use an xpath expression to find all of the child nodes. */ 4754 4755 if ( self->doc == NULL ) { 4756 croak("Node passed to toStringC14N must be part of a document"); 4757 } 4758 4759 refNode = self; 4760 CODE: 4761 if ( xpath != NULL && xpath != &PL_sv_undef ) { 4762 nodepath = Sv2C( xpath, NULL ); 4763 } 4764 4765 if ( nodepath != NULL && xmlStrlen( nodepath ) == 0 ) { 4766 xmlFree( nodepath ); 4767 nodepath = NULL; 4768 } 4769 4770 if ( nodepath == NULL 4771 && self->type != XML_DOCUMENT_NODE 4772 && self->type != XML_HTML_DOCUMENT_NODE 4773 && self->type != XML_DOCB_DOCUMENT_NODE 4774 ) { 4775 if (comments) 4776 nodepath = xmlStrdup( (const xmlChar *) "(. | .//node() | .//@* | .//namespace::*)" ); 4777 else 4778 nodepath = xmlStrdup( (const xmlChar *) "(. | .//node() | .//@* | .//namespace::*)[not(self::comment())]" ); 4779 } 4780 4781 if ( nodepath != NULL ) { 4782 if ( self->type == XML_DOCUMENT_NODE 4783 || self->type == XML_HTML_DOCUMENT_NODE 4784 || self->type == XML_DOCB_DOCUMENT_NODE ) { 4785 refNode = xmlDocGetRootElement( self->doc ); 4786 } 4787 4788 child_ctxt = xmlXPathNewContext(self->doc); 4789 if (!child_ctxt) { 4790 if ( nodepath != NULL ) { 4791 xmlFree( nodepath ); 4792 } 4793 croak("Failed to create xpath context"); 4794 } 4795 4796 child_ctxt->node = self; 4797 /* get the namespace information */ 4798 if (self->type == XML_DOCUMENT_NODE) { 4799 child_ctxt->namespaces = xmlGetNsList( self->doc, 4800 xmlDocGetRootElement( self->doc ) ); 4801 } 4802 else { 4803 child_ctxt->namespaces = xmlGetNsList(self->doc, self); 4804 } 4805 child_ctxt->nsNr = 0; 4806 if (child_ctxt->namespaces != NULL) { 4807 while (child_ctxt->namespaces[child_ctxt->nsNr] != NULL) 4808 child_ctxt->nsNr++; 4809 } 4810 4811 child_xpath = xmlXPathEval(nodepath, child_ctxt); 4812 if (child_xpath == NULL) { 4813 if (child_ctxt->namespaces != NULL) { 4814 xmlFree( child_ctxt->namespaces ); 4815 } 4816 xmlXPathFreeContext(child_ctxt); 4817 if ( nodepath != NULL ) { 4818 xmlFree( nodepath ); 4819 } 4820 croak("2 Failed to compile xpath expression"); 4821 } 4822 4823 nodelist = child_xpath->nodesetval; 4824 if ( nodelist == NULL ) { 4825 xmlFree( nodepath ); 4826 xmlXPathFreeObject(child_xpath); 4827 if (child_ctxt->namespaces != NULL) { 4828 xmlFree( child_ctxt->namespaces ); 4829 } 4830 xmlXPathFreeContext(child_ctxt); 4831 croak( "cannot canonize empty nodeset!" ); 4832 } 4833 } 4834 4835 LibXML_init_error_ctx(saved_error); 4836 4837 xmlC14NDocDumpMemory( self->doc, 4838 nodelist, 4839 exclusive, (xmlChar **) inc_prefix_list, 4840 comments, 4841 &result ); 4842 4843 if ( child_xpath ) { 4844 xmlXPathFreeObject(child_xpath); 4845 } 4846 if ( child_ctxt ) { 4847 if (child_ctxt->namespaces != NULL) { 4848 xmlFree( child_ctxt->namespaces ); 4849 } 4850 xmlXPathFreeContext(child_ctxt); 4851 } 4852 if ( nodepath != NULL ) { 4853 xmlFree( nodepath ); 4854 } 4855 4856 LibXML_report_error_ctx(saved_error, 0); 4857 4858 if (result == NULL) { 4859 croak("Failed to convert doc to string in doc->toStringC14N"); 4860 } else { 4861 RETVAL = C2Sv( result, NULL ); 4862 xmlFree(result); 4863 } 4864 OUTPUT: 4865 RETVAL 4866 4867SV* 4868string_value ( self, useDomEncoding = &PL_sv_undef ) 4869 xmlNodePtr self 4870 SV * useDomEncoding 4871 ALIAS: 4872 to_literal = 1 4873 textContent = 2 4874 PREINIT: 4875 xmlChar * string = NULL; 4876 CODE: 4877 /* we can't just return a string, because of UTF8! */ 4878 string = xmlXPathCastNodeToString(self); 4879 if ( SvTRUE(useDomEncoding) ) { 4880 RETVAL = nodeC2Sv(string, 4881 self); 4882 } 4883 else { 4884 RETVAL = C2Sv(string, 4885 NULL); 4886 } 4887 xmlFree(string); 4888 OUTPUT: 4889 RETVAL 4890 4891double 4892to_number ( self ) 4893 xmlNodePtr self 4894 CODE: 4895 RETVAL = xmlXPathCastNodeToNumber(self); 4896 OUTPUT: 4897 RETVAL 4898 4899 4900void 4901_find( pnode, pxpath ) 4902 SV* pnode 4903 SV * pxpath 4904 PREINIT: 4905 SV * saved_error = sv_2mortal(newSVpv("",0)); 4906 xmlNodePtr node = PmmSvNode(pnode); 4907 ProxyNodePtr owner = NULL; 4908 xmlXPathObjectPtr found = NULL; 4909 xmlNodeSetPtr nodelist = NULL; 4910 STRLEN len = 0 ; 4911 xmlChar * xpath = nodeSv2C(pxpath, node); 4912 INIT: 4913 if ( node == NULL ) { 4914 croak( "lost node" ); 4915 } 4916 if ( !(xpath && xmlStrlen(xpath)) ) { 4917 xs_warn( "bad xpath\n" ); 4918 if ( xpath ) 4919 xmlFree(xpath); 4920 croak( "empty XPath found" ); 4921 XSRETURN_UNDEF; 4922 } 4923 PPCODE: 4924 if ( node->doc ) { 4925 domNodeNormalize( xmlDocGetRootElement( node->doc ) ); 4926 } 4927 else { 4928 domNodeNormalize( PmmOWNER(SvPROXYNODE(pnode)) ); 4929 } 4930 4931 LibXML_init_error_ctx(saved_error); 4932 4933 found = domXPathFind( node, xpath ); 4934 xmlFree( xpath ); 4935 4936 if (found) { 4937 switch (found->type) { 4938 case XPATH_NODESET: 4939 /* return as a NodeList */ 4940 /* access ->nodesetval */ 4941 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::NodeList", 0))); 4942 nodelist = found->nodesetval; 4943 if ( nodelist ) { 4944 if ( nodelist->nodeNr > 0 ) { 4945 int i; 4946 const char * cls = "XML::LibXML::Node"; 4947 xmlNodePtr tnode; 4948 SV * element; 4949 4950 owner = PmmOWNERPO(SvPROXYNODE(pnode)); 4951 len = nodelist->nodeNr; 4952 for( i=0 ; i < len; i++){ 4953 /* we have to create a new instance of an 4954 * objectptr. and then 4955 * place the current node into the new 4956 * object. afterwards we can 4957 * push the object to the array! 4958 */ 4959 tnode = nodelist->nodeTab[i]; 4960 4961 /* let's be paranoid */ 4962 if (tnode->type == XML_NAMESPACE_DECL) { 4963 xmlNsPtr newns = xmlCopyNamespace((xmlNsPtr)tnode); 4964 if ( newns != NULL ) { 4965 element = NEWSV(0,0); 4966 cls = PmmNodeTypeName( tnode ); 4967 element = sv_setref_pv( element, 4968 (const char *)cls, 4969 (void*)newns 4970 ); 4971 } 4972 else { 4973 continue; 4974 } 4975 } 4976 else { 4977 element = PmmNodeToSv(tnode, owner); 4978 } 4979 4980 XPUSHs( sv_2mortal(element) ); 4981 } 4982 } 4983 xmlXPathFreeNodeSet( found->nodesetval ); 4984 found->nodesetval = NULL; 4985 } 4986 break; 4987 case XPATH_BOOLEAN: 4988 /* return as a Boolean */ 4989 /* access ->boolval */ 4990 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Boolean", 0))); 4991 XPUSHs(sv_2mortal(newSViv(found->boolval))); 4992 break; 4993 case XPATH_NUMBER: 4994 /* return as a Number */ 4995 /* access ->floatval */ 4996 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Number", 0))); 4997 XPUSHs(sv_2mortal(newSVnv(found->floatval))); 4998 break; 4999 case XPATH_STRING: 5000 /* access ->stringval */ 5001 /* return as a Literal */ 5002 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Literal", 0))); 5003 XPUSHs(sv_2mortal(C2Sv(found->stringval, NULL))); 5004 break; 5005 default: 5006 croak("Unknown XPath return type"); 5007 } 5008 xmlXPathFreeObject(found); 5009 } 5010 5011 LibXML_report_error_ctx(saved_error, 0); 5012 5013void 5014_findnodes( pnode, perl_xpath ) 5015 SV* pnode 5016 SV * perl_xpath 5017 PREINIT: 5018 SV * saved_error = sv_2mortal(newSVpv("",0)); 5019 xmlNodePtr node = PmmSvNode(pnode); 5020 ProxyNodePtr owner = NULL; 5021 xmlNodeSetPtr nodelist = NULL; 5022 SV * element = NULL ; 5023 STRLEN len = 0 ; 5024 xmlChar * xpath = nodeSv2C(perl_xpath, node); 5025 INIT: 5026 if ( node == NULL ) { 5027 croak( "lost node" ); 5028 } 5029 if ( !(xpath && xmlStrlen(xpath)) ) { 5030 xs_warn( "bad xpath\n" ); 5031 if ( xpath ) 5032 xmlFree(xpath); 5033 croak( "empty XPath found" ); 5034 XSRETURN_UNDEF; 5035 } 5036 PPCODE: 5037 if ( node->doc ) { 5038 domNodeNormalize( xmlDocGetRootElement(node->doc ) ); 5039 } 5040 else { 5041 domNodeNormalize( PmmOWNER(SvPROXYNODE(pnode)) ); 5042 } 5043 5044 LibXML_init_error_ctx(saved_error); 5045 5046 nodelist = domXPathSelect( node, xpath ); 5047 xmlFree(xpath); 5048 5049 if ( nodelist ) { 5050 if ( nodelist->nodeNr > 0 ) { 5051 int i; 5052 const char * cls = "XML::LibXML::Node"; 5053 xmlNodePtr tnode; 5054 owner = PmmOWNERPO(SvPROXYNODE(pnode)); 5055 len = nodelist->nodeNr; 5056 for(i=0 ; i < len; i++){ 5057 /* we have to create a new instance of an objectptr. 5058 * and then place the current node into the new object. 5059 * afterwards we can push the object to the array! 5060 */ 5061 element = NULL; 5062 tnode = nodelist->nodeTab[i]; 5063 if (tnode->type == XML_NAMESPACE_DECL) { 5064 xmlNsPtr newns = xmlCopyNamespace((xmlNsPtr)tnode); 5065 if ( newns != NULL ) { 5066 element = NEWSV(0,0); 5067 cls = PmmNodeTypeName( tnode ); 5068 element = sv_setref_pv( element, 5069 (const char *)cls, 5070 newns 5071 ); 5072 } 5073 else { 5074 continue; 5075 } 5076 } 5077 else { 5078 element = PmmNodeToSv(tnode, owner); 5079 } 5080 5081 XPUSHs( sv_2mortal(element) ); 5082 } 5083 } 5084 xmlXPathFreeNodeSet( nodelist ); 5085 } 5086 5087 LibXML_report_error_ctx(saved_error, 0); 5088 5089void 5090getNamespaces( pnode ) 5091 SV * pnode 5092 ALIAS: 5093 namespaces = 1 5094 PREINIT: 5095 xmlNodePtr node; 5096 xmlNsPtr ns = NULL; 5097 xmlNsPtr newns = NULL; 5098 SV* element = &PL_sv_undef; 5099 const char * class = "XML::LibXML::Namespace"; 5100 INIT: 5101 node = PmmSvNode(pnode); 5102 if ( node == NULL ) { 5103 croak( "lost node" ); 5104 } 5105 PPCODE: 5106 ns = node->nsDef; 5107 while ( ns != NULL ) { 5108 if (ns->prefix != NULL || ns->href != NULL) { 5109 newns = xmlCopyNamespace(ns); 5110 if ( newns != NULL ) { 5111 element = NEWSV(0,0); 5112 element = sv_setref_pv( element, 5113 (const char *)class, 5114 (void*)newns 5115 ); 5116 XPUSHs( sv_2mortal(element) ); 5117 } 5118 } 5119 ns = ns->next; 5120 } 5121 5122SV * 5123getNamespace( node ) 5124 xmlNodePtr node 5125 ALIAS: 5126 localNamespace = 1 5127 localNS = 2 5128 PREINIT: 5129 xmlNsPtr ns = NULL; 5130 xmlNsPtr newns = NULL; 5131 const char * class = "XML::LibXML::Namespace"; 5132 CODE: 5133 ns = node->ns; 5134 if ( ns != NULL ) { 5135 newns = xmlCopyNamespace(ns); 5136 if ( newns != NULL ) { 5137 RETVAL = NEWSV(0,0); 5138 RETVAL = sv_setref_pv( RETVAL, 5139 (const char *)class, 5140 (void*)newns 5141 ); 5142 } else { 5143 XSRETURN_UNDEF; 5144 } 5145 } 5146 else { 5147 XSRETURN_UNDEF; 5148 } 5149 OUTPUT: 5150 RETVAL 5151 5152 5153SV * 5154nodePath( self ) 5155 xmlNodePtr self 5156 PREINIT: 5157 xmlChar * path = NULL; 5158 CODE: 5159 path = xmlGetNodePath( self ); 5160 if ( path == NULL ) { 5161 croak( "cannot calculate path for the given node" ); 5162 } 5163 RETVAL = nodeC2Sv( path, self ); 5164 xmlFree(path); 5165 OUTPUT: 5166 RETVAL 5167 5168int 5169line_number( self ) 5170 xmlNodePtr self 5171 CODE: 5172 RETVAL = xmlGetLineNo( self ); 5173 OUTPUT: 5174 RETVAL 5175 5176MODULE = XML::LibXML PACKAGE = XML::LibXML::Element 5177 5178SV* 5179new(CLASS, name ) 5180 char * CLASS 5181 char * name 5182 PREINIT: 5183 xmlNodePtr newNode; 5184 ProxyNodePtr docfrag; 5185 CODE: 5186 docfrag = PmmNewFragment(NULL); 5187 newNode = xmlNewNode( NULL, (const xmlChar*)name ); 5188 newNode->doc = NULL; 5189 xmlAddChild(PmmNODE(docfrag), newNode); 5190 RETVAL = PmmNodeToSv(newNode, docfrag ); 5191 OUTPUT: 5192 RETVAL 5193 5194int 5195_setNamespace(self, namespaceURI, namespacePrefix = &PL_sv_undef, flag = 1 ) 5196 SV * self 5197 SV * namespaceURI 5198 SV * namespacePrefix 5199 int flag 5200 PREINIT: 5201 xmlNodePtr node = PmmSvNode(self); 5202 xmlChar * nsURI = nodeSv2C(namespaceURI,node); 5203 xmlChar * nsPrefix = NULL; 5204 xmlNsPtr ns = NULL; 5205 INIT: 5206 if ( node == NULL ) { 5207 croak( "lost node" ); 5208 } 5209 CODE: 5210 /* if ( !nsURI ){ 5211 XSRETURN_UNDEF; 5212 } */ 5213 5214 nsPrefix = nodeSv2C(namespacePrefix, node); 5215 if ( xmlStrlen( nsPrefix ) == 0 ) { 5216 xmlFree(nsPrefix); 5217 nsPrefix = NULL; 5218 } 5219 if ( xmlStrlen( nsURI ) == 0 ) { 5220 xmlFree(nsURI); 5221 nsURI = NULL; 5222 } 5223 if ( nsPrefix == NULL && nsURI == NULL ) { 5224 /* special case: empty namespace */ 5225 if ( (ns = xmlSearchNs(node->doc, node, NULL)) && 5226 ( ns->href && xmlStrlen( ns->href ) != 0 ) ) { 5227 /* won't take it */ 5228 RETVAL = 0; 5229 } else if ( flag ) { 5230 /* no namespace */ 5231 xmlSetNs(node, NULL); 5232 RETVAL = 1; 5233 } else { 5234 RETVAL = 0; 5235 } 5236 } 5237 else if ( flag && (ns = xmlSearchNs(node->doc, node, nsPrefix)) ) { 5238 /* user just wants to set the namespace for the node */ 5239 /* try to reuse an existing declaration for the prefix */ 5240 if ( xmlStrEqual( ns->href, nsURI ) ) { 5241 RETVAL = 1; 5242 } 5243 else if ( (ns = xmlNewNs( node, nsURI, nsPrefix )) ) { 5244 RETVAL = 1; 5245 } 5246 else { 5247 RETVAL = 0; 5248 } 5249 } 5250 else if ( (ns = xmlNewNs( node, nsURI, nsPrefix )) ) 5251 RETVAL = 1; 5252 else 5253 RETVAL = 0; 5254 5255 if ( flag && ns ) { 5256 xmlSetNs(node, ns); 5257 } 5258 if ( nsPrefix ) xmlFree(nsPrefix); 5259 if ( nsURI ) xmlFree(nsURI); 5260 OUTPUT: 5261 RETVAL 5262 5263 5264SV* 5265_getNamespaceDeclURI( self, ns_prefix ) 5266 xmlNodePtr self 5267 SV * ns_prefix 5268 PREINIT: 5269 xmlChar * prefix; 5270 xmlNsPtr ns; 5271 CODE: 5272 prefix = nodeSv2C(ns_prefix, self ); 5273 if ( prefix != NULL && xmlStrlen(prefix) == 0) { 5274 xmlFree( prefix ); 5275 prefix = NULL; 5276 } 5277 RETVAL = &PL_sv_undef; 5278 ns = self->nsDef; 5279 while ( ns != NULL ) { 5280 if ( (ns->prefix != NULL || ns->href != NULL) && 5281 xmlStrcmp( ns->prefix, prefix ) == 0 ) { 5282 RETVAL = C2Sv(ns->href, NULL); 5283 break; 5284 } else { 5285 ns = ns->next; 5286 } 5287 } 5288 if ( prefix != NULL ) { 5289 xmlFree( prefix ); 5290 } 5291 5292 OUTPUT: 5293 RETVAL 5294 5295int 5296hasAttribute( self, attr_name ) 5297 xmlNodePtr self 5298 SV * attr_name 5299 PREINIT: 5300 xmlChar * name; 5301 CODE: 5302 name = nodeSv2C(attr_name, self ); 5303 if ( ! name ) { 5304 XSRETURN_UNDEF; 5305 } 5306 if ( domGetAttrNode( self, name ) ) { 5307 RETVAL = 1; 5308 } 5309 else { 5310 RETVAL = 0; 5311 } 5312 xmlFree(name); 5313 OUTPUT: 5314 RETVAL 5315 5316int 5317hasAttributeNS( self, namespaceURI, attr_name ) 5318 xmlNodePtr self 5319 SV * namespaceURI 5320 SV * attr_name 5321 PREINIT: 5322 xmlChar * name; 5323 xmlChar * nsURI; 5324 xmlNodePtr attr; 5325 CODE: 5326 name = nodeSv2C(attr_name, self ); 5327 nsURI = nodeSv2C(namespaceURI, self ); 5328 5329 if ( name == NULL ) { 5330 if ( nsURI != NULL ) { 5331 xmlFree(nsURI); 5332 } 5333 XSRETURN_UNDEF; 5334 } 5335 if ( nsURI != NULL && xmlStrlen(nsURI) == 0 ){ 5336 xmlFree(nsURI); 5337 nsURI = NULL; 5338 } 5339 attr = (xmlNodePtr) xmlHasNsProp( self, name, nsURI ); 5340 if ( attr && attr->type == XML_ATTRIBUTE_NODE ) { 5341 RETVAL = 1; 5342 } 5343 else { 5344 RETVAL = 0; 5345 } 5346 5347 xmlFree(name); 5348 if ( nsURI != NULL ){ 5349 xmlFree(nsURI); 5350 } 5351 OUTPUT: 5352 RETVAL 5353 5354SV* 5355_getAttribute( self, attr_name, doc_enc = 0 ) 5356 xmlNodePtr self 5357 SV * attr_name 5358 int doc_enc 5359 PREINIT: 5360 xmlChar * name; 5361 xmlChar * prefix = NULL; 5362 xmlChar * localname = NULL; 5363 xmlChar * ret = NULL; 5364 xmlNsPtr ns = NULL; 5365 CODE: 5366 name = nodeSv2C(attr_name, self ); 5367 if( !name ) { 5368 XSRETURN_UNDEF; 5369 } 5370 5371 ret = xmlGetNoNsProp(self, name); 5372 if ( ret == NULL ) { 5373 localname = xmlSplitQName2(name, &prefix); 5374 if ( localname != NULL ) { 5375 ns = xmlSearchNs( self->doc, self, prefix ); 5376 if ( ns != NULL ) { 5377 ret = xmlGetNsProp(self, localname, ns->href); 5378 } 5379 if ( prefix != NULL) { 5380 xmlFree( prefix ); 5381 } 5382 xmlFree( localname ); 5383 } 5384 } 5385 xmlFree(name); 5386 if ( ret ) { 5387 if ( doc_enc == 1 ) { 5388 RETVAL = nodeC2Sv(ret, self); 5389 } 5390 else { 5391 RETVAL = C2Sv(ret, NULL); 5392 } 5393 xmlFree( ret ); 5394 } 5395 else { 5396 XSRETURN_UNDEF; 5397 } 5398 5399 OUTPUT: 5400 RETVAL 5401 5402void 5403_setAttribute( self, attr_name, attr_value ) 5404 xmlNodePtr self 5405 SV * attr_name 5406 SV * attr_value 5407 PREINIT: 5408 xmlChar * name = NULL; 5409 xmlChar * value = NULL; 5410#if LIBXML_VERSION < 20621 5411 xmlChar * prefix = NULL; 5412 xmlChar * localname = NULL; 5413#endif 5414 CODE: 5415 name = nodeSv2C(attr_name, self ); 5416 5417 if ( !LibXML_test_node_name(name) ) { 5418 xmlFree(name); 5419 croak( "bad name" ); 5420 } 5421 value = nodeSv2C(attr_value, self ); 5422#if LIBXML_VERSION >= 20621 5423 /* 5424 * For libxml2-2.6.21 and later we can use just xmlSetProp 5425 */ 5426 xmlSetProp(self,name,value); 5427#else 5428 /* 5429 * but xmlSetProp does not work correctly for older libxml2 versions 5430 * The following is copied from libxml2 source 5431 * with xmlSplitQName3 replaced by xmlSplitQName2 for compatibility 5432 * with older libxml2 versions 5433 */ 5434 localname = xmlSplitQName2(name, &prefix); 5435 if (localname != NULL) { 5436 xmlNsPtr ns; 5437 ns = xmlSearchNs(self->doc, self, prefix); 5438 if (prefix != NULL) 5439 xmlFree(prefix); 5440 if (ns != NULL) 5441 xmlSetNsProp(self, ns, localname, value); 5442 else 5443 xmlSetNsProp(self, NULL, name, value); 5444 xmlFree(localname); 5445 } else { 5446 xmlSetNsProp(self, NULL, name, value); 5447 } 5448#endif 5449 xmlFree(name); 5450 xmlFree(value); 5451 5452 5453void 5454removeAttribute( self, attr_name ) 5455 xmlNodePtr self 5456 SV * attr_name 5457 PREINIT: 5458 xmlChar * name; 5459 xmlAttrPtr xattr = NULL; 5460 CODE: 5461 name = nodeSv2C(attr_name, self ); 5462 if ( name ) { 5463 xattr = domGetAttrNode( self, name ); 5464 5465 if ( xattr ) { 5466 xmlUnlinkNode((xmlNodePtr)xattr); 5467 if ( xattr->_private ) { 5468 PmmFixOwner((ProxyNodePtr)xattr->_private, NULL); 5469 } 5470 else { 5471 xmlFreeProp(xattr); 5472 } 5473 } 5474 xmlFree(name); 5475 } 5476 5477SV* 5478getAttributeNode( self, attr_name ) 5479 xmlNodePtr self 5480 SV * attr_name 5481 PREINIT: 5482 xmlChar * name; 5483 xmlAttrPtr ret = NULL; 5484 CODE: 5485 name = nodeSv2C(attr_name, self ); 5486 if ( !name ) { 5487 XSRETURN_UNDEF; 5488 } 5489 5490 ret = domGetAttrNode( self, name ); 5491 xmlFree(name); 5492 if ( ret ) { 5493 RETVAL = PmmNodeToSv( (xmlNodePtr)ret, 5494 PmmOWNERPO(PmmPROXYNODE(self)) ); 5495 } 5496 else { 5497 XSRETURN_UNDEF; 5498 } 5499 OUTPUT: 5500 RETVAL 5501 5502SV * 5503setAttributeNode( self, attr_node ) 5504 xmlNodePtr self 5505 SV * attr_node 5506 PREINIT: 5507 xmlAttrPtr attr = (xmlAttrPtr)PmmSvNode( attr_node ); 5508 xmlAttrPtr ret = NULL; 5509 INIT: 5510 if ( attr == NULL ) { 5511 croak( "lost attribute" ); 5512 } 5513 CODE: 5514 if ( attr != NULL && attr->type != XML_ATTRIBUTE_NODE ) { 5515 XSRETURN_UNDEF; 5516 } 5517 if ( attr->doc != self->doc ) { 5518 domImportNode( self->doc, (xmlNodePtr)attr, 1, 1); 5519 } 5520 ret = domGetAttrNode( self, attr->name ); 5521 if ( ret != NULL ) { 5522 if ( ret != attr ) { 5523 xmlReplaceNode( (xmlNodePtr)ret, (xmlNodePtr)attr ); 5524 } 5525 else { 5526 XSRETURN_UNDEF; 5527 } 5528 } 5529 else { 5530 xmlAddChild( self, (xmlNodePtr)attr ); 5531 } 5532 5533 if ( attr->_private != NULL ) { 5534 PmmFixOwner( SvPROXYNODE(attr_node), PmmPROXYNODE(self) ); 5535 } 5536 5537 if ( ret == NULL ) { 5538 XSRETURN_UNDEF; 5539 } 5540 5541 RETVAL = PmmNodeToSv( (xmlNodePtr)ret, NULL ); 5542 PmmFixOwner( SvPROXYNODE(RETVAL), NULL ); 5543 OUTPUT: 5544 RETVAL 5545 5546SV * 5547_getAttributeNS( self, namespaceURI, attr_name ) 5548 xmlNodePtr self 5549 SV * namespaceURI 5550 SV * attr_name 5551 PREINIT: 5552 xmlChar * name; 5553 xmlChar * nsURI; 5554 xmlChar * ret = NULL; 5555 CODE: 5556 name = nodeSv2C( attr_name, self ); 5557 nsURI = nodeSv2C( namespaceURI, self ); 5558 if ( !name ) { 5559 xmlFree(nsURI); 5560 XSRETURN_UNDEF; 5561 } 5562 if ( nsURI && xmlStrlen(nsURI) ) { 5563 ret = xmlGetNsProp( self, name, nsURI ); 5564 } 5565 else { 5566 ret = xmlGetProp( self, name ); 5567 } 5568 5569 xmlFree( name ); 5570 if ( nsURI ) { 5571 xmlFree( nsURI ); 5572 } 5573 if ( ret ) { 5574 RETVAL = nodeC2Sv( ret, self ); 5575 xmlFree( ret ); 5576 } 5577 else { 5578 XSRETURN_UNDEF; 5579 } 5580 OUTPUT: 5581 RETVAL 5582 5583void 5584_setAttributeNS( self, namespaceURI, attr_name, attr_value ) 5585 xmlNodePtr self 5586 SV * namespaceURI 5587 SV * attr_name 5588 SV * attr_value 5589 PREINIT: 5590 xmlChar * nsURI; 5591 xmlChar * name = NULL; 5592 xmlChar * value = NULL; 5593 xmlNsPtr ns = NULL; 5594 xmlChar * localname = NULL; 5595 xmlChar * prefix = NULL; 5596 INIT: 5597 name = nodeSv2C( attr_name, self ); 5598 5599 if ( !LibXML_test_node_name(name) ) { 5600 xmlFree(name); 5601 croak( "bad name" ); 5602 } 5603 5604 nsURI = nodeSv2C( namespaceURI, self ); 5605 localname = xmlSplitQName2(name, &prefix); 5606 if ( localname ) { 5607 xmlFree( name ); 5608 name = localname; 5609 } 5610 CODE: 5611 value = nodeSv2C( attr_value, self ); 5612 5613 if ( nsURI && xmlStrlen(nsURI) ) { 5614 xs_warn( "found uri" ); 5615 5616 ns = xmlSearchNsByHref( self->doc, self, nsURI ); 5617 if ( !ns ) { 5618 /* create new ns */ 5619 if ( prefix && xmlStrlen( prefix ) ) { 5620 ns = xmlNewNs(self, nsURI , prefix ); 5621 } 5622 else { 5623 ns = NULL; 5624 } 5625 } 5626 else if ( !ns->prefix ) { 5627 if ( ns->next && ns->next->prefix ) { 5628 ns = ns->next; 5629 } 5630 else if ( prefix && xmlStrlen( prefix ) ) { 5631 ns = xmlNewNs(self, nsURI , prefix ); 5632 } 5633 else { 5634 ns = NULL; 5635 } 5636 } 5637 } 5638 5639 if ( nsURI && xmlStrlen(nsURI) && !ns ) { 5640 if ( prefix ) xmlFree( prefix ); 5641 if ( nsURI ) xmlFree( nsURI ); 5642 xmlFree( name ); 5643 xmlFree( value ); 5644 croak( "bad ns attribute!" ); 5645 } 5646 else { 5647 /* warn( "set attribute %s->%s", name, value ); */ 5648 xmlSetNsProp( self, ns, name, value ); 5649 } 5650 5651 if ( prefix ) { 5652 xmlFree( prefix ); 5653 } 5654 if ( nsURI ) { 5655 xmlFree( nsURI ); 5656 } 5657 xmlFree( name ); 5658 xmlFree( value ); 5659 5660void 5661removeAttributeNS( self, namespaceURI, attr_name ) 5662 xmlNodePtr self 5663 SV * namespaceURI 5664 SV * attr_name 5665 PREINIT: 5666 xmlChar * nsURI; 5667 xmlChar * name = NULL; 5668 xmlAttrPtr xattr = NULL; 5669 CODE: 5670 nsURI = nodeSv2C( namespaceURI, self ); 5671 name = nodeSv2C( attr_name, self ); 5672 if ( ! name ) { 5673 xmlFree(nsURI); 5674 XSRETURN_UNDEF; 5675 } 5676 5677 if ( nsURI && xmlStrlen(nsURI) ) { 5678 xattr = xmlHasNsProp( self, name, nsURI ); 5679 } 5680 else { 5681 xattr = xmlHasNsProp( self, name, NULL ); 5682 } 5683 if ( xattr && xattr->type == XML_ATTRIBUTE_NODE ) { 5684 xmlUnlinkNode((xmlNodePtr)xattr); 5685 if ( xattr->_private ) { 5686 PmmFixOwner((ProxyNodePtr)xattr->_private, NULL); 5687 } 5688 else { 5689 xmlFreeProp(xattr); 5690 } 5691 } 5692 xmlFree(nsURI); 5693 xmlFree( name ); 5694 5695 5696SV* 5697getAttributeNodeNS( self,namespaceURI, attr_name ) 5698 xmlNodePtr self 5699 SV * namespaceURI 5700 SV * attr_name 5701 PREINIT: 5702 xmlChar * nsURI; 5703 xmlChar * name; 5704 xmlAttrPtr ret = NULL; 5705 CODE: 5706 nsURI = nodeSv2C(namespaceURI, self ); 5707 name = nodeSv2C(attr_name, self ); 5708 if ( !name ) { 5709 xmlFree(nsURI); 5710 XSRETURN_UNDEF; 5711 } 5712 if ( nsURI && xmlStrlen(nsURI) ) { 5713 ret = xmlHasNsProp( self, name, nsURI ); 5714 } 5715 else { 5716 ret = xmlHasNsProp( self, name, NULL ); 5717 } 5718 xmlFree(name); 5719 if ( nsURI ) { 5720 xmlFree(nsURI); 5721 } 5722 if ( ret && 5723 ret->type == XML_ATTRIBUTE_NODE /* we don't want fixed attribute decls */ 5724 ) { 5725 RETVAL = PmmNodeToSv( (xmlNodePtr)ret, 5726 PmmOWNERPO(PmmPROXYNODE(self)) ); 5727 } 5728 else { 5729 /* warn("no prop\n"); */ 5730 XSRETURN_UNDEF; 5731 } 5732 OUTPUT: 5733 RETVAL 5734 5735SV * 5736setAttributeNodeNS( self, attr_node ) 5737 xmlNodePtr self 5738 SV * attr_node 5739 PREINIT: 5740 xmlAttrPtr attr = (xmlAttrPtr)PmmSvNode( attr_node ); 5741 xmlNsPtr ns = NULL; 5742 xmlAttrPtr ret = NULL; 5743 INIT: 5744 if ( attr == NULL ) { 5745 croak( "lost attribute node" ); 5746 } 5747 CODE: 5748 if ( attr->type != XML_ATTRIBUTE_NODE ) { 5749 XSRETURN_UNDEF; 5750 } 5751 5752 if ( attr->doc != self->doc ) { 5753 domImportNode( self->doc, (xmlNodePtr)attr, 1,1); 5754 } 5755 5756 5757 ns = attr->ns; 5758 if ( ns != NULL ) { 5759 ret = xmlHasNsProp( self, ns->href, attr->name ); 5760 } 5761 else { 5762 ret = xmlHasNsProp( self, NULL, attr->name ); 5763 } 5764 5765 if ( ret && ret->type == XML_ATTRIBUTE_NODE ) { 5766 if ( ret != attr ) { 5767 xmlReplaceNode( (xmlNodePtr)ret, (xmlNodePtr)attr ); 5768 } 5769 else { 5770 XSRETURN_UNDEF; 5771 } 5772 } 5773 else { 5774 xmlAddChild( self, (xmlNodePtr)attr ); 5775 xmlReconciliateNs(self->doc, self); 5776 } 5777 if ( attr->_private != NULL ) { 5778 PmmFixOwner( SvPROXYNODE(attr_node), PmmPROXYNODE(self) ); 5779 } 5780 if ( ret != NULL && ret->type == XML_ATTRIBUTE_NODE ) { 5781 RETVAL = PmmNodeToSv( (xmlNodePtr)ret, NULL ); 5782 PmmFixOwner( SvPROXYNODE(RETVAL), NULL ); 5783 } else { 5784 XSRETURN_UNDEF; 5785 } 5786 OUTPUT: 5787 RETVAL 5788 5789SV * 5790removeAttributeNode( self, attr_node ) 5791 xmlNodePtr self 5792 SV * attr_node 5793 PREINIT: 5794 xmlAttrPtr attr = (xmlAttrPtr)PmmSvNode( attr_node ); 5795 xmlAttrPtr ret; 5796 INIT: 5797 if ( attr == NULL ) { 5798 croak( "lost attribute node" ); 5799 } 5800 CODE: 5801 if ( attr->type != XML_ATTRIBUTE_NODE ) { 5802 XSRETURN_UNDEF; 5803 } 5804 if ( attr->parent != self ) { 5805 XSRETURN_UNDEF; 5806 } 5807 ret = attr; 5808 xmlUnlinkNode( (xmlNodePtr)attr ); 5809 RETVAL = PmmNodeToSv( (xmlNodePtr)ret, NULL ); 5810 PmmFixOwner( SvPROXYNODE(RETVAL), NULL ); 5811 OUTPUT: 5812 RETVAL 5813 5814void 5815appendText( self, string ) 5816 xmlNodePtr self 5817 SV * string 5818 ALIAS: 5819 appendTextNode = 1 5820 XML::LibXML::DocumentFragment::appendText = 2 5821 XML::LibXML::DocumentFragment::appendTextNode = 3 5822 PREINIT: 5823 xmlChar * content = NULL; 5824 INIT: 5825 content = nodeSv2C( string, self ); 5826 if ( content == NULL ) { 5827 XSRETURN_UNDEF; 5828 } 5829 if ( xmlStrlen(content) == 0 ) { 5830 xmlFree( content ); 5831 XSRETURN_UNDEF; 5832 } 5833 CODE: 5834 xmlNodeAddContent( self, content ); 5835 xmlFree(content); 5836 5837 5838void 5839appendTextChild( self, strname, strcontent=&PL_sv_undef, nsURI=&PL_sv_undef ) 5840 xmlNodePtr self 5841 SV * strname 5842 SV * strcontent 5843 SV * nsURI 5844 PREINIT: 5845 xmlChar * name; 5846 xmlChar * content = NULL; 5847 xmlChar * encstr = NULL; 5848 INIT: 5849 name = nodeSv2C( strname, self ); 5850 if ( xmlStrlen(name) == 0 ) { 5851 xmlFree(name); 5852 XSRETURN_UNDEF; 5853 } 5854 CODE: 5855 content = nodeSv2C(strcontent, self); 5856 if ( content && xmlStrlen( content ) == 0 ) { 5857 xmlFree(content); 5858 content=NULL; 5859 } 5860 else if ( content ) { 5861 encstr = xmlEncodeEntitiesReentrant( self->doc, content ); 5862 xmlFree(content); 5863 } 5864 5865 xmlNewChild( self, NULL, name, encstr ); 5866 5867 if ( encstr ) 5868 xmlFree(encstr); 5869 xmlFree(name); 5870 5871SV * 5872addNewChild( self, namespaceURI, nodename ) 5873 xmlNodePtr self 5874 SV * namespaceURI 5875 SV * nodename 5876 ALIAS: 5877 XML::LibXML::DocumentFragment::addNewChild = 1 5878 PREINIT: 5879 xmlChar * nsURI = NULL; 5880 xmlChar * name = NULL; 5881 xmlChar * localname = NULL; 5882 xmlChar * prefix = NULL; 5883 xmlNodePtr newNode = NULL; 5884 xmlNodePtr prev = NULL; 5885 xmlNsPtr ns = NULL; 5886 CODE: 5887 name = nodeSv2C(nodename, self); 5888 if ( name && xmlStrlen( name ) == 0 ) { 5889 xmlFree(name); 5890 XSRETURN_UNDEF; 5891 } 5892 5893 nsURI = nodeSv2C(namespaceURI, self); 5894 if ( nsURI && xmlStrlen( nsURI ) == 0 ) { 5895 xmlFree(nsURI); 5896 nsURI=NULL; 5897 } 5898 5899 if ( nsURI != NULL ) { 5900 localname = xmlSplitQName2(name, &prefix); 5901 ns = xmlSearchNsByHref(self->doc, self, nsURI); 5902 5903 newNode = xmlNewDocNode(self->doc, 5904 ns, 5905 localname?localname:name, 5906 NULL); 5907 if ( ns == NULL ) { 5908 xmlSetNs(newNode,xmlNewNs(newNode, nsURI, prefix)); 5909 } 5910 5911 xmlFree(localname); 5912 xmlFree(prefix); 5913 xmlFree(nsURI); 5914 } 5915 else { 5916 newNode = xmlNewDocNode(self->doc, 5917 NULL, 5918 name, 5919 NULL); 5920 } 5921 xmlFree(name); 5922 /* add the node to the parent node */ 5923 newNode->type = XML_ELEMENT_NODE; 5924 newNode->parent = self; 5925 newNode->doc = self->doc; 5926 5927 if (self->children == NULL) { 5928 self->children = newNode; 5929 self->last = newNode; 5930 } else { 5931 prev = self->last; 5932 prev->next = newNode; 5933 newNode->prev = prev; 5934 self->last = newNode; 5935 } 5936 RETVAL = PmmNodeToSv(newNode, PmmOWNERPO(PmmPROXYNODE(self)) ); 5937 OUTPUT: 5938 RETVAL 5939 5940MODULE = XML::LibXML PACKAGE = XML::LibXML::Text 5941 5942SV * 5943new( CLASS, content ) 5944 const char * CLASS 5945 SV * content 5946 PREINIT: 5947 xmlChar * data; 5948 xmlNodePtr newNode; 5949 ProxyNodePtr docfrag = NULL; 5950 CODE: 5951 data = Sv2C(content, NULL); 5952 newNode = xmlNewText( data ); 5953 xmlFree(data); 5954 if( newNode != NULL ) { 5955 docfrag = PmmNewFragment( NULL ); 5956 xmlAddChild(PmmNODE(docfrag), newNode); 5957 RETVAL = PmmNodeToSv(newNode,docfrag); 5958 } 5959 else { 5960 XSRETURN_UNDEF; 5961 } 5962 OUTPUT: 5963 RETVAL 5964 5965SV * 5966substringData( self, offset, length ) 5967 xmlNodePtr self 5968 int offset 5969 int length 5970 PREINIT: 5971 xmlChar * data = NULL; 5972 xmlChar * substr = NULL; 5973 int len = 0; 5974 int dl = 0; 5975 CODE: 5976 if ( offset >= 0 && length > 0 ) { 5977 dl = offset + length - 1 ; 5978 data = domGetNodeValue( self ); 5979 len = xmlStrlen( data ); 5980 if ( data != NULL && len > 0 && len > offset ) { 5981 if ( dl > len ) 5982 dl = offset + len; 5983 5984 substr = xmlStrsub( data, offset, dl ); 5985 RETVAL = C2Sv( (const xmlChar*)substr, NULL ); 5986 xmlFree( substr ); 5987 } 5988 else { 5989 XSRETURN_UNDEF; 5990 } 5991 } 5992 else { 5993 XSRETURN_UNDEF; 5994 } 5995 OUTPUT: 5996 RETVAL 5997 5998void 5999setData( self, value ) 6000 xmlNodePtr self 6001 SV * value 6002 ALIAS: 6003 XML::LibXML::Attr::setValue = 1 6004 XML::LibXML::PI::_setData = 2 6005 PREINIT: 6006 xmlChar * encstr = NULL; 6007 CODE: 6008 encstr = nodeSv2C(value,self); 6009 domSetNodeValue( self, encstr ); 6010 xmlFree(encstr); 6011 6012void 6013appendData( self, value ) 6014 xmlNodePtr self 6015 SV * value 6016 PREINIT: 6017 xmlChar * encstring = NULL; 6018 int strlen = 0; 6019 CODE: 6020 encstring = Sv2C( value, 6021 self->doc!=NULL ? self->doc->encoding : NULL ); 6022 6023 if ( encstring != NULL ) { 6024 strlen = xmlStrlen( encstring ); 6025 xmlTextConcat( self, encstring, strlen ); 6026 xmlFree( encstring ); 6027 } 6028 6029void 6030insertData( self, offset, value ) 6031 xmlNodePtr self 6032 int offset 6033 SV * value 6034 PREINIT: 6035 xmlChar * after= NULL; 6036 xmlChar * data = NULL; 6037 xmlChar * new = NULL; 6038 xmlChar * encstring = NULL; 6039 int dl = 0; 6040 CODE: 6041 if ( offset >= 0 ) { 6042 encstring = Sv2C( value, 6043 self->doc!=NULL ? self->doc->encoding : NULL ); 6044 if ( encstring != NULL && xmlStrlen( encstring ) > 0 ) { 6045 data = domGetNodeValue(self); 6046 if ( data != NULL && xmlStrlen( data ) > 0 ) { 6047 if ( xmlStrlen( data ) < offset ) { 6048 data = xmlStrcat( data, encstring ); 6049 domSetNodeValue( self, data ); 6050 } 6051 else { 6052 dl = xmlStrlen( data ) - offset; 6053 6054 if ( offset > 0 ) 6055 new = xmlStrsub(data, 0, offset ); 6056 6057 after = xmlStrsub(data, offset, dl ); 6058 6059 if ( new != NULL ) { 6060 new = xmlStrcat(new, encstring ); 6061 } 6062 else { 6063 new = xmlStrdup( encstring ); 6064 } 6065 6066 if ( after != NULL ) 6067 new = xmlStrcat(new, after ); 6068 6069 domSetNodeValue( self, new ); 6070 6071 xmlFree( new ); 6072 xmlFree( after ); 6073 } 6074 xmlFree( data ); 6075 } 6076 else { 6077 domSetNodeValue( self, encstring ); 6078 } 6079 xmlFree(encstring); 6080 } 6081 } 6082 6083void 6084deleteData( self, offset, length ) 6085 xmlNodePtr self 6086 int offset 6087 int length 6088 PREINIT: 6089 xmlChar * data = NULL; 6090 xmlChar * after = NULL; 6091 xmlChar * new = NULL; 6092 int len = 0; 6093 int dl1 = 0; 6094 int dl2 = 0; 6095 CODE: 6096 if ( length > 0 && offset >= 0 ) { 6097 data = domGetNodeValue(self); 6098 len = xmlStrlen( data ); 6099 if ( data != NULL 6100 && len > 0 6101 && len > offset ) { 6102 dl1 = offset + length; 6103 if ( offset > 0 ) 6104 new = xmlStrsub( data, 0, offset ); 6105 6106 if ( len > dl1 ) { 6107 dl2 = len - dl1; 6108 after = xmlStrsub( data, dl1, dl2 ); 6109 if ( new != NULL ) { 6110 new = xmlStrcat( new, after ); 6111 xmlFree(after); 6112 } 6113 else { 6114 new = after; 6115 } 6116 } 6117 6118 domSetNodeValue( self, new ); 6119 xmlFree(new); 6120 } 6121 } 6122 6123void 6124replaceData( self, offset,length, value ) 6125 xmlNodePtr self 6126 int offset 6127 int length 6128 SV * value 6129 PREINIT: 6130 xmlChar * after= NULL; 6131 xmlChar * data = NULL; 6132 xmlChar * new = NULL; 6133 xmlChar * encstring = NULL; 6134 int len = 0; 6135 int dl1 = 0; 6136 int dl2 = 0; 6137 CODE: 6138 if ( offset >= 0 ) { 6139 encstring = Sv2C( value, 6140 self->doc!=NULL ? self->doc->encoding : NULL ); 6141 6142 if ( encstring != NULL && xmlStrlen( encstring ) > 0 ) { 6143 data = domGetNodeValue(self); 6144 len = xmlStrlen( data ); 6145 6146 if ( data != NULL 6147 && len > 0 6148 && len > offset ) { 6149 6150 dl1 = offset + length; 6151 if ( dl1 < len ) { 6152 dl2 = xmlStrlen( data ) - dl1; 6153 if ( offset > 0 ) { 6154 new = xmlStrsub(data, 0, offset ); 6155 new = xmlStrcat(new, encstring ); 6156 } 6157 else { 6158 new = xmlStrdup( encstring ); 6159 } 6160 6161 after = xmlStrsub(data, dl1, dl2 ); 6162 new = xmlStrcat(new, after ); 6163 6164 domSetNodeValue( self, new ); 6165 6166 xmlFree( new ); 6167 xmlFree( after ); 6168 } 6169 else { 6170 /* replace until end! */ 6171 if ( offset > 0 ) { 6172 new = xmlStrsub(data, 0, offset ); 6173 new = xmlStrcat(new, encstring ); 6174 } 6175 else { 6176 new = xmlStrdup( encstring ); 6177 } 6178 domSetNodeValue( self, new ); 6179 xmlFree( new ); 6180 } 6181 xmlFree( data ); 6182 } 6183 6184 xmlFree(encstring); 6185 } 6186 } 6187 6188MODULE = XML::LibXML PACKAGE = XML::LibXML::Comment 6189 6190SV * 6191new( CLASS, content ) 6192 const char * CLASS 6193 SV * content 6194 PREINIT: 6195 xmlChar * encstring; 6196 xmlNodePtr newNode; 6197 ProxyNodePtr docfrag = NULL; 6198 CODE: 6199 encstring = Sv2C(content, NULL); 6200 newNode = xmlNewComment( encstring ); 6201 xmlFree(encstring); 6202 if( newNode != NULL ) { 6203 docfrag = PmmNewFragment( NULL ); 6204 xmlAddChild(PmmNODE(docfrag), newNode); 6205 RETVAL = PmmNodeToSv(newNode,docfrag); 6206 } 6207 else { 6208 XSRETURN_UNDEF; 6209 } 6210 OUTPUT: 6211 RETVAL 6212 6213MODULE = XML::LibXML PACKAGE = XML::LibXML::CDATASection 6214 6215SV * 6216new( CLASS , content ) 6217 const char * CLASS 6218 SV * content 6219 PREINIT: 6220 xmlChar * encstring; 6221 xmlNodePtr newNode; 6222 ProxyNodePtr docfrag = NULL; 6223 CODE: 6224 encstring = Sv2C(content, NULL); 6225 newNode = xmlNewCDataBlock( NULL , encstring, xmlStrlen( encstring ) ); 6226 xmlFree(encstring); 6227 if ( newNode != NULL ){ 6228 docfrag = PmmNewFragment( NULL ); 6229 xmlAddChild(PmmNODE(docfrag), newNode); 6230 RETVAL = PmmNodeToSv(newNode,docfrag); 6231 } 6232 else { 6233 XSRETURN_UNDEF; 6234 } 6235 OUTPUT: 6236 RETVAL 6237 6238MODULE = XML::LibXML PACKAGE = XML::LibXML::DocumentFragment 6239 6240SV* 6241new( CLASS ) 6242 char * CLASS 6243 PREINIT: 6244 xmlNodePtr real_doc=NULL; 6245 CODE: 6246 real_doc = xmlNewDocFragment( NULL ); 6247 RETVAL = PmmNodeToSv( real_doc, NULL ); 6248 OUTPUT: 6249 RETVAL 6250 6251MODULE = XML::LibXML PACKAGE = XML::LibXML::Attr 6252 6253SV* 6254new( CLASS, pname, pvalue ) 6255 char * CLASS 6256 SV * pname 6257 SV * pvalue 6258 PREINIT: 6259 xmlNodePtr attr = NULL; 6260 xmlChar * name; 6261 xmlChar * value; 6262 CODE: 6263 name = Sv2C(pname,NULL); 6264 value = Sv2C(pvalue,NULL); 6265 if ( name == NULL ) { 6266 XSRETURN_UNDEF; 6267 } 6268 attr = (xmlNodePtr)xmlNewProp( NULL, name, value ); 6269 attr->doc = NULL; 6270 RETVAL = PmmNodeToSv(attr,NULL); 6271 OUTPUT: 6272 RETVAL 6273 6274 6275SV* 6276parentElement( attrnode ) 6277 SV * attrnode 6278 ALIAS: 6279 XML::LibXML::Attr::getParentNode = 1 6280 XML::LibXML::Attr::getNextSibling = 2 6281 XML::LibXML::Attr::getPreviousSibling = 3 6282 XML::LibXML::Attr::nextSibling = 4 6283 XML::LibXML::Attr::previousSibling = 5 6284 CODE: 6285 /* override the original parentElement(), since this an attribute is 6286 * not part of the main tree 6287 */ 6288 6289 XSRETURN_UNDEF; 6290 OUTPUT: 6291 RETVAL 6292 6293SV* 6294serializeContent( self, useDomEncoding = &PL_sv_undef ) 6295 SV * self 6296 SV * useDomEncoding 6297 PREINIT: 6298 xmlBufferPtr buffer; 6299 const xmlChar *ret = NULL; 6300 xmlAttrPtr node = (xmlAttrPtr)PmmSvNode(self); 6301 CODE: 6302 buffer = xmlBufferCreate(); 6303 domAttrSerializeContent(buffer, node); 6304 if ( xmlBufferLength(buffer) > 0 ) { 6305 ret = xmlBufferContent( buffer ); 6306 } 6307 if ( ret != NULL ) { 6308 if ( useDomEncoding != &PL_sv_undef && SvTRUE(useDomEncoding) ) { 6309 RETVAL = nodeC2Sv((xmlChar*)ret, PmmNODE(PmmPROXYNODE(node))) ; 6310 } 6311 else { 6312 RETVAL = C2Sv((xmlChar*)ret, NULL) ; 6313 } 6314 xmlBufferFree( buffer ); 6315 } 6316 else { 6317 xmlBufferFree( buffer ); 6318 xs_warn("Failed to convert attribute to string"); 6319 XSRETURN_UNDEF; 6320 } 6321 OUTPUT: 6322 RETVAL 6323 6324SV* 6325toString(self , format=0, useDomEncoding = &PL_sv_undef ) 6326 SV * self 6327 SV * useDomEncoding 6328 int format 6329 ALIAS: 6330 XML::LibXML::Attr::serialize = 1 6331 PREINIT: 6332 xmlAttrPtr node = (xmlAttrPtr)PmmSvNode(self); 6333 xmlBufferPtr buffer; 6334 const xmlChar *ret = NULL; 6335 CODE: 6336 /* we add an extra method for serializing attributes since 6337 XML::LibXML::Node::toString causes segmentation fault inside 6338 libxml2 6339 */ 6340 buffer = xmlBufferCreate(); 6341 xmlBufferAdd(buffer, BAD_CAST " ", 1); 6342 if ((node->ns != NULL) && (node->ns->prefix != NULL)) { 6343 xmlBufferAdd(buffer, node->ns->prefix, xmlStrlen(node->ns->prefix)); 6344 xmlBufferAdd(buffer, BAD_CAST ":", 1); 6345 } 6346 xmlBufferAdd(buffer, node->name, xmlStrlen(node->name)); 6347 xmlBufferAdd(buffer, BAD_CAST "=\"", 2); 6348 domAttrSerializeContent(buffer, node); 6349 xmlBufferAdd(buffer, BAD_CAST "\"", 1); 6350 6351 if ( xmlBufferLength(buffer) > 0 ) { 6352 ret = xmlBufferContent( buffer ); 6353 } 6354 if ( ret != NULL ) { 6355 if ( useDomEncoding != &PL_sv_undef && SvTRUE(useDomEncoding) ) { 6356 RETVAL = nodeC2Sv((xmlChar*)ret, PmmNODE(PmmPROXYNODE(node))) ; 6357 } 6358 else { 6359 RETVAL = C2Sv((xmlChar*)ret, NULL) ; 6360 } 6361 xmlBufferFree( buffer ); 6362 } 6363 else { 6364 xmlBufferFree( buffer ); 6365 xs_warn("Failed to convert attribute to string"); 6366 XSRETURN_UNDEF; 6367 } 6368 OUTPUT: 6369 RETVAL 6370 6371 6372int 6373_setNamespace(self, namespaceURI, namespacePrefix = &PL_sv_undef ) 6374 SV * self 6375 SV * namespaceURI 6376 SV * namespacePrefix 6377 PREINIT: 6378 xmlAttrPtr node = (xmlAttrPtr)PmmSvNode(self); 6379 xmlChar * nsURI = nodeSv2C(namespaceURI,(xmlNodePtr)node); 6380 xmlChar * nsPrefix = NULL; 6381 xmlNsPtr ns = NULL; 6382 INIT: 6383 if ( node == NULL ) { 6384 croak( "lost node" ); 6385 } 6386 CODE: 6387 if ( !nsURI || xmlStrlen(nsURI)==0 ){ 6388 xmlSetNs((xmlNodePtr)node, NULL); 6389 RETVAL = 1; 6390 } 6391 if ( !node->parent ) { 6392 XSRETURN_UNDEF; 6393 } 6394 nsPrefix = nodeSv2C(namespacePrefix, (xmlNodePtr)node); 6395 if ( (ns = xmlSearchNs(node->doc, node->parent, nsPrefix)) && 6396 xmlStrEqual( ns->href, nsURI) ) { 6397 /* same uri and prefix */ 6398 RETVAL = 1; 6399 } 6400 else if ( (ns = xmlSearchNsByHref(node->doc, node->parent, nsURI)) ) { 6401 /* set uri, but with a different prefix */ 6402 RETVAL = 1; 6403 } 6404 else 6405 RETVAL = 0; 6406 6407 if ( ns ) { 6408 if ( ns->prefix ) { 6409 xmlSetNs((xmlNodePtr)node, ns); 6410 } else { 6411 RETVAL = 0; 6412 } 6413 } 6414 xmlFree(nsPrefix); 6415 xmlFree(nsURI); 6416 OUTPUT: 6417 RETVAL 6418 6419int 6420isId( self ) 6421 SV * self 6422 PREINIT: 6423 xmlAttrPtr attr = (xmlAttrPtr)PmmSvNode(self); 6424 xmlNodePtr elem; 6425 CODE: 6426 if ( attr == NULL ) { 6427 XSRETURN_UNDEF; 6428 } 6429 elem = attr->parent; 6430 if ( elem == NULL || elem->doc == NULL ) { 6431 XSRETURN_UNDEF; 6432 } 6433 RETVAL = xmlIsID( elem->doc, elem, attr ); 6434 OUTPUT: 6435 RETVAL 6436 6437MODULE = XML::LibXML PACKAGE = XML::LibXML::Namespace 6438 6439SV* 6440new(CLASS, namespaceURI, namespacePrefix=&PL_sv_undef) 6441 const char * CLASS 6442 SV * namespaceURI 6443 SV * namespacePrefix 6444 PREINIT: 6445 xmlNsPtr ns = NULL; 6446 xmlChar* nsURI; 6447 xmlChar* nsPrefix; 6448 CODE: 6449 RETVAL = &PL_sv_undef; 6450 6451 nsURI = Sv2C(namespaceURI,NULL); 6452 if ( !nsURI ) { 6453 XSRETURN_UNDEF; 6454 } 6455 nsPrefix = Sv2C(namespacePrefix, NULL); 6456 ns = xmlNewNs(NULL, nsURI, nsPrefix); 6457 if ( ns ) { 6458 RETVAL = sv_newmortal(); 6459 RETVAL = sv_setref_pv( RETVAL, 6460 CLASS, 6461 (void*)ns); 6462 } 6463 xmlFree(nsURI); 6464 if ( nsPrefix ) 6465 xmlFree(nsPrefix); 6466 OUTPUT: 6467 RETVAL 6468 6469void 6470DESTROY(self) 6471 SV * self 6472 PREINIT: 6473 xmlNsPtr ns = (xmlNsPtr)SvIV(SvRV(self)); 6474 CODE: 6475 xs_warn( "DESTROY NS" ); 6476 if (ns) { 6477 xmlFreeNs(ns); 6478 } 6479 6480int 6481nodeType(self) 6482 SV * self 6483 ALIAS: 6484 getType = 1 6485 PREINIT: 6486 xmlNsPtr ns = (xmlNsPtr)SvIV(SvRV(self)); 6487 CODE: 6488 RETVAL = ns->type; 6489 OUTPUT: 6490 RETVAL 6491 6492SV* 6493declaredURI(self) 6494 SV * self 6495 ALIAS: 6496 value = 1 6497 nodeValue = 2 6498 getData = 3 6499 getValue = 4 6500 value = 5 6501 href = 6 6502 PREINIT: 6503 xmlNsPtr ns = (xmlNsPtr)SvIV(SvRV(self)); 6504 xmlChar * href; 6505 CODE: 6506 href = xmlStrdup(ns->href); 6507 RETVAL = C2Sv(href, NULL); 6508 xmlFree(href); 6509 OUTPUT: 6510 RETVAL 6511 6512SV* 6513declaredPrefix(self) 6514 SV * self 6515 ALIAS: 6516 localname = 1 6517 getLocalName = 2 6518 PREINIT: 6519 xmlNsPtr ns = (xmlNsPtr)SvIV(SvRV(self)); 6520 xmlChar * prefix; 6521 CODE: 6522 prefix = xmlStrdup(ns->prefix); 6523 RETVAL = C2Sv(prefix, NULL); 6524 xmlFree(prefix); 6525 OUTPUT: 6526 RETVAL 6527 6528int 6529_isEqual(self, ref) 6530 SV * self 6531 SV * ref 6532 PREINIT: 6533 xmlNsPtr ns = (xmlNsPtr)SvIV(SvRV(self)); 6534 xmlNsPtr ons = (xmlNsPtr)SvIV(SvRV(ref)); 6535 CODE: 6536 RETVAL = 0; 6537 if ( ns == ons ) { 6538 RETVAL = 1; 6539 } 6540 else if ( xmlStrEqual(ns->href, ons->href) 6541 && xmlStrEqual(ns->prefix, ons->prefix) ) { 6542 RETVAL = 1; 6543 } 6544 OUTPUT: 6545 RETVAL 6546 6547 6548MODULE = XML::LibXML PACKAGE = XML::LibXML::Dtd 6549 6550SV * 6551new(CLASS, external, system) 6552 char * CLASS 6553 char * external 6554 char * system 6555 ALIAS: 6556 parse_uri = 1 6557 PREINIT: 6558 SV * saved_error = sv_2mortal(newSVpv("",0)); 6559 xmlDtdPtr dtd = NULL; 6560 CODE: 6561 LibXML_init_error_ctx(saved_error); 6562 dtd = xmlParseDTD((const xmlChar*)external, (const xmlChar*)system); 6563 if ( dtd == NULL ) { 6564 LibXML_report_error_ctx(saved_error, 0); 6565 XSRETURN_UNDEF; 6566 } else { 6567 xmlSetTreeDoc((xmlNodePtr)dtd, NULL); 6568 RETVAL = PmmNodeToSv( (xmlNodePtr) dtd, NULL ); 6569 LibXML_report_error_ctx(saved_error, 0); 6570 } 6571 OUTPUT: 6572 RETVAL 6573 6574SV* 6575systemId( self ) 6576 xmlDtdPtr self 6577 ALIAS: 6578 getSystemId = 1 6579 CODE: 6580 if ( self->SystemID == NULL ) { 6581 XSRETURN_UNDEF; 6582 } else { 6583 RETVAL = C2Sv(self->SystemID,NULL); 6584 } 6585 OUTPUT: 6586 RETVAL 6587 6588SV* 6589publicId( self ) 6590 xmlDtdPtr self 6591 ALIAS: 6592 getPublicId = 1 6593 CODE: 6594 if ( self->ExternalID == NULL ) { 6595 XSRETURN_UNDEF; 6596 } else { 6597 RETVAL = C2Sv(self->ExternalID,NULL); 6598 } 6599 OUTPUT: 6600 RETVAL 6601 6602void 6603DESTROY( node ) 6604 SV * node 6605 CODE: 6606 xs_warn("DESTROY DTD NODE\n"); 6607 PmmREFCNT_dec(SvPROXYNODE(node)); 6608 6609SV * 6610parse_string(CLASS, str, ...) 6611 char * CLASS 6612 char * str 6613 PREINIT: 6614 SV * saved_error = sv_2mortal(newSVpv("",0)); 6615 xmlDtdPtr res; 6616 SV * encoding_sv; 6617 xmlParserInputBufferPtr buffer; 6618 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; 6619 xmlChar * new_string; 6620 CODE: 6621 LibXML_init_error_ctx(saved_error); 6622 if (items > 2) { 6623 encoding_sv = ST(2); 6624 if (items > 3) { 6625 croak("parse_string: too many parameters"); 6626 } 6627 /* warn("getting encoding...\n"); */ 6628 enc = xmlParseCharEncoding(SvPV_nolen(encoding_sv)); 6629 if (enc == XML_CHAR_ENCODING_ERROR) { 6630 LibXML_report_error_ctx(saved_error, 1); 6631 croak("Parse of encoding %s failed", SvPV_nolen(encoding_sv)); 6632 } 6633 } 6634 buffer = xmlAllocParserInputBuffer(enc); 6635 /* buffer = xmlParserInputBufferCreateMem(str, xmlStrlen(str), enc); */ 6636 if ( !buffer) 6637 croak("cannot create buffer!\n" ); 6638 6639 new_string = xmlStrdup((const xmlChar*)str); 6640 xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string); 6641 6642 res = xmlIOParseDTD(NULL, buffer, enc); 6643 6644 /* NOTE: xmlIOParseDTD is documented to free its InputBuffer */ 6645 xmlFree(new_string); 6646 if ( res && LibXML_will_die_ctx(saved_error, 0) ) 6647 xmlFreeDtd( res ); 6648 LibXML_report_error_ctx(saved_error, 0); 6649 if (res == NULL) { 6650 croak("no DTD parsed!"); 6651 } 6652 RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL); 6653 OUTPUT: 6654 RETVAL 6655 6656 6657#ifdef HAVE_SCHEMAS 6658 6659MODULE = XML::LibXML PACKAGE = XML::LibXML::RelaxNG 6660 6661void 6662DESTROY( self ) 6663 xmlRelaxNGPtr self 6664 CODE: 6665 xmlRelaxNGFree( self ); 6666 6667 6668xmlRelaxNGPtr 6669parse_location( self, url ) 6670 SV * self 6671 char * url 6672 PREINIT: 6673 SV * saved_error = sv_2mortal(newSVpv("",0)); 6674 const char * CLASS = "XML::LibXML::RelaxNG"; 6675 xmlRelaxNGParserCtxtPtr rngctxt = NULL; 6676 CODE: 6677 LibXML_init_error_ctx(saved_error); 6678 6679 rngctxt = xmlRelaxNGNewParserCtxt( url ); 6680 if ( rngctxt == NULL ) { 6681 croak( "failed to initialize RelaxNG parser" ); 6682 } 6683 6684 /* Register Error callbacks */ 6685 xmlRelaxNGSetParserErrors( rngctxt, 6686 (xmlRelaxNGValidityErrorFunc)LibXML_error_handler_ctx, 6687 (xmlRelaxNGValidityWarningFunc)LibXML_error_handler_ctx, 6688 saved_error ); 6689 6690 RETVAL = xmlRelaxNGParse( rngctxt ); 6691 xmlRelaxNGFreeParserCtxt( rngctxt ); 6692 6693 LibXML_report_error_ctx(saved_error, (RETVAL != NULL)); 6694 OUTPUT: 6695 RETVAL 6696 6697 6698xmlRelaxNGPtr 6699parse_buffer( self, perlstring ) 6700 SV * self 6701 SV * perlstring 6702 PREINIT: 6703 SV * saved_error = sv_2mortal(newSVpv("",0)); 6704 const char * CLASS = "XML::LibXML::RelaxNG"; 6705 xmlRelaxNGParserCtxtPtr rngctxt = NULL; 6706 char * string = NULL; 6707 STRLEN len = 0; 6708 INIT: 6709 string = SvPV( perlstring, len ); 6710 if ( string == NULL ) { 6711 croak( "cannot parse empty string" ); 6712 } 6713 CODE: 6714 LibXML_init_error_ctx(saved_error); 6715 6716 rngctxt = xmlRelaxNGNewMemParserCtxt( string,len ); 6717 if ( rngctxt == NULL ) { 6718 croak( "failed to initialize RelaxNG parser" ); 6719 } 6720 6721 /* Register Error callbacks */ 6722 xmlRelaxNGSetParserErrors( rngctxt, 6723 (xmlRelaxNGValidityErrorFunc)LibXML_error_handler_ctx, 6724 (xmlRelaxNGValidityWarningFunc)LibXML_error_handler_ctx, 6725 saved_error ); 6726 6727 RETVAL = xmlRelaxNGParse( rngctxt ); 6728 xmlRelaxNGFreeParserCtxt( rngctxt ); 6729 6730 LibXML_report_error_ctx(saved_error, (RETVAL != NULL)); 6731 OUTPUT: 6732 RETVAL 6733 6734 6735xmlRelaxNGPtr 6736parse_document( self, doc ) 6737 SV * self 6738 xmlDocPtr doc 6739 PREINIT: 6740 SV * saved_error = sv_2mortal(newSVpv("",0)); 6741 const char * CLASS = "XML::LibXML::RelaxNG"; 6742 xmlRelaxNGParserCtxtPtr rngctxt = NULL; 6743 CODE: 6744 LibXML_init_error_ctx(saved_error); 6745 6746 rngctxt = xmlRelaxNGNewDocParserCtxt( doc ); 6747 if ( rngctxt == NULL ) { 6748 croak( "failed to initialize RelaxNG parser" ); 6749 } 6750 6751 /* Register Error callbacks */ 6752 xmlRelaxNGSetParserErrors( rngctxt, 6753 (xmlRelaxNGValidityErrorFunc) LibXML_error_handler_ctx, 6754 (xmlRelaxNGValidityWarningFunc)LibXML_error_handler_ctx, 6755 saved_error ); 6756 6757 RETVAL = xmlRelaxNGParse( rngctxt ); 6758 xmlRelaxNGFreeParserCtxt( rngctxt ); 6759 6760 LibXML_report_error_ctx(saved_error, (RETVAL != NULL)); 6761 OUTPUT: 6762 RETVAL 6763 6764int 6765validate( self, doc ) 6766 xmlRelaxNGPtr self 6767 xmlDocPtr doc 6768 PREINIT: 6769 SV * saved_error = sv_2mortal(newSVpv("",0)); 6770 xmlRelaxNGValidCtxtPtr vctxt = NULL; 6771 CODE: 6772 LibXML_init_error_ctx(saved_error); 6773 6774 vctxt = xmlRelaxNGNewValidCtxt( self ); 6775 if ( vctxt == NULL ) { 6776 croak( "cannot initialize the validation context" ); 6777 } 6778 6779 /* Register Error callbacks */ 6780 xmlRelaxNGSetValidErrors( vctxt, 6781 (xmlRelaxNGValidityErrorFunc)LibXML_error_handler_ctx, 6782 (xmlRelaxNGValidityWarningFunc)LibXML_error_handler_ctx, 6783 saved_error ); 6784 /* ** test only ** 6785 xmlRelaxNGSetValidErrors( vctxt, 6786 (xmlRelaxNGValidityErrorFunc)fprintf, 6787 (xmlRelaxNGValidityWarningFunc)fprintf, 6788 stderr ); 6789 */ 6790 RETVAL = xmlRelaxNGValidateDoc( vctxt, doc ); 6791 xmlRelaxNGFreeValidCtxt( vctxt ); 6792 6793 LibXML_report_error_ctx(saved_error, 0); 6794 if ( RETVAL == 1 ) { 6795 XSRETURN_UNDEF; 6796 } 6797 if ( RETVAL == -1 ) { 6798 croak( "API Error" ); 6799 XSRETURN_UNDEF; 6800 } 6801 OUTPUT: 6802 RETVAL 6803 6804 6805MODULE = XML::LibXML PACKAGE = XML::LibXML::Schema 6806 6807void 6808DESTROY( self ) 6809 xmlSchemaPtr self 6810 CODE: 6811 xmlSchemaFree( self ); 6812 6813 6814xmlSchemaPtr 6815parse_location( self, url ) 6816 SV * self 6817 char * url 6818 PREINIT: 6819 SV * saved_error = sv_2mortal(newSVpv("",0)); 6820 const char * CLASS = "XML::LibXML::Schema"; 6821 xmlSchemaParserCtxtPtr rngctxt = NULL; 6822 CODE: 6823 LibXML_init_error_ctx(saved_error); 6824 6825 rngctxt = xmlSchemaNewParserCtxt( url ); 6826 if ( rngctxt == NULL ) { 6827 croak( "failed to initialize Schema parser" ); 6828 } 6829 6830 /* Register Error callbacks */ 6831 xmlSchemaSetParserErrors( rngctxt, 6832 (xmlSchemaValidityErrorFunc)LibXML_error_handler_ctx, 6833 (xmlSchemaValidityWarningFunc)LibXML_error_handler_ctx, 6834 saved_error ); 6835 6836 RETVAL = xmlSchemaParse( rngctxt ); 6837 xmlSchemaFreeParserCtxt( rngctxt ); 6838 6839 LibXML_report_error_ctx(saved_error, (RETVAL != NULL)); 6840 OUTPUT: 6841 RETVAL 6842 6843 6844xmlSchemaPtr 6845parse_buffer( self, perlstring ) 6846 SV * self 6847 SV * perlstring 6848 PREINIT: 6849 SV * saved_error = sv_2mortal(newSVpv("",0)); 6850 const char * CLASS = "XML::LibXML::Schema"; 6851 xmlSchemaParserCtxtPtr rngctxt = NULL; 6852 char * string = NULL; 6853 STRLEN len = 0; 6854 INIT: 6855 string = SvPV( perlstring, len ); 6856 if ( string == NULL ) { 6857 croak( "cannot parse empty string" ); 6858 } 6859 CODE: 6860 LibXML_init_error_ctx(saved_error); 6861 6862 rngctxt = xmlSchemaNewMemParserCtxt( string,len ); 6863 if ( rngctxt == NULL ) { 6864 croak( "failed to initialize Schema parser" ); 6865 } 6866 6867 /* Register Error callbacks */ 6868 xmlSchemaSetParserErrors( rngctxt, 6869 (xmlSchemaValidityErrorFunc)LibXML_error_handler_ctx, 6870 (xmlSchemaValidityWarningFunc)LibXML_error_handler_ctx, 6871 saved_error ); 6872 6873 RETVAL = xmlSchemaParse( rngctxt ); 6874 xmlSchemaFreeParserCtxt( rngctxt ); 6875 6876 LibXML_report_error_ctx(saved_error, (RETVAL != NULL)); 6877 OUTPUT: 6878 RETVAL 6879 6880 6881int 6882validate( self, doc ) 6883 xmlSchemaPtr self 6884 xmlDocPtr doc 6885 PREINIT: 6886 SV * saved_error = sv_2mortal(newSVpv("",0)); 6887 xmlSchemaValidCtxtPtr vctxt = NULL; 6888 CODE: 6889 LibXML_init_error_ctx(saved_error); 6890 6891 vctxt = xmlSchemaNewValidCtxt( self ); 6892 if ( vctxt == NULL ) { 6893 croak( "cannot initialize the validation context" ); 6894 } 6895 6896 /* Register Error callbacks */ 6897 xmlSchemaSetValidErrors( vctxt, 6898 (xmlSchemaValidityErrorFunc)LibXML_error_handler_ctx, 6899 (xmlSchemaValidityWarningFunc)LibXML_error_handler_ctx, 6900 saved_error ); 6901 6902 RETVAL = xmlSchemaValidateDoc( vctxt, doc ); 6903 xmlSchemaFreeValidCtxt( vctxt ); 6904 6905 LibXML_report_error_ctx(saved_error, 0); 6906 if ( RETVAL > 0 ) { 6907 XSRETURN_UNDEF; 6908 } 6909 if ( RETVAL == -1 ) { 6910 croak( "API Error" ); 6911 XSRETURN_UNDEF; 6912 } 6913 OUTPUT: 6914 RETVAL 6915 6916#endif /* HAVE_SCHEMAS */ 6917 6918MODULE = XML::LibXML::XPathContext PACKAGE = XML::LibXML::XPathContext 6919 6920# PROTOTYPES: DISABLE 6921 6922SV* 6923new( CLASS, ... ) 6924 const char * CLASS 6925 PREINIT: 6926 SV * pnode = &PL_sv_undef; 6927 INIT: 6928 xmlXPathContextPtr ctxt; 6929 CODE: 6930 if( items > 1 ) 6931 pnode = ST(1); 6932 6933 ctxt = xmlXPathNewContext( NULL ); 6934 ctxt->namespaces = NULL; 6935 6936 New(0, ctxt->user, sizeof(XPathContextData), XPathContextData); 6937 if (ctxt->user == NULL) { 6938 croak("XPathContext: failed to allocate proxy object\n"); 6939 } 6940 6941 if (SvOK(pnode)) { 6942 XPathContextDATA(ctxt)->node = newSVsv(pnode); 6943 } else { 6944 XPathContextDATA(ctxt)->node = &PL_sv_undef; 6945 } 6946 6947 XPathContextDATA(ctxt)->pool = NULL; 6948 XPathContextDATA(ctxt)->varLookup = NULL; 6949 XPathContextDATA(ctxt)->varData = NULL; 6950 6951 xmlXPathRegisterFunc(ctxt, 6952 (const xmlChar *) "document", 6953 perlDocumentFunction); 6954 6955 RETVAL = NEWSV(0,0), 6956 RETVAL = sv_setref_pv( RETVAL, 6957 CLASS, 6958 (void*)ctxt ); 6959 OUTPUT: 6960 RETVAL 6961 6962void 6963DESTROY( self ) 6964 SV * self 6965 INIT: 6966 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 6967 CODE: 6968 xs_warn( "DESTROY XPATH CONTEXT" ); 6969 if (ctxt) { 6970 if (XPathContextDATA(ctxt) != NULL) { 6971 if (XPathContextDATA(ctxt)->node != NULL && 6972 SvOK(XPathContextDATA(ctxt)->node)) { 6973 SvREFCNT_dec(XPathContextDATA(ctxt)->node); 6974 } 6975 if (XPathContextDATA(ctxt)->varLookup != NULL && 6976 SvOK(XPathContextDATA(ctxt)->varLookup)) { 6977 SvREFCNT_dec(XPathContextDATA(ctxt)->varLookup); 6978 } 6979 if (XPathContextDATA(ctxt)->varData != NULL && 6980 SvOK(XPathContextDATA(ctxt)->varData)) { 6981 SvREFCNT_dec(XPathContextDATA(ctxt)->varData); 6982 } 6983 if (XPathContextDATA(ctxt)->pool != NULL && 6984 SvOK(XPathContextDATA(ctxt)->pool)) { 6985 SvREFCNT_dec((SV *)XPathContextDATA(ctxt)->pool); 6986 } 6987 Safefree(XPathContextDATA(ctxt)); 6988 } 6989 6990 if (ctxt->namespaces != NULL) { 6991 xmlFree( ctxt->namespaces ); 6992 } 6993 if (ctxt->funcLookupData != NULL && SvROK((SV*)ctxt->funcLookupData) 6994 && SvTYPE(SvRV((SV *)ctxt->funcLookupData)) == SVt_PVHV) { 6995 SvREFCNT_dec((SV *)ctxt->funcLookupData); 6996 } 6997 6998 xmlXPathFreeContext(ctxt); 6999 } 7000 7001SV* 7002getContextNode( self ) 7003 SV * self 7004 INIT: 7005 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7006 if ( ctxt == NULL ) { 7007 croak("XPathContext: missing xpath context\n"); 7008 } 7009 CODE: 7010 if(XPathContextDATA(ctxt)->node != NULL) { 7011 RETVAL = newSVsv(XPathContextDATA(ctxt)->node); 7012 } else { 7013 RETVAL = &PL_sv_undef; 7014 } 7015 OUTPUT: 7016 RETVAL 7017 7018int 7019getContextPosition( self ) 7020 SV * self 7021 INIT: 7022 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7023 if ( ctxt == NULL ) { 7024 croak("XPathContext: missing xpath context\n"); 7025 } 7026 CODE: 7027 RETVAL = ctxt->proximityPosition; 7028 OUTPUT: 7029 RETVAL 7030 7031int 7032getContextSize( self ) 7033 SV * self 7034 INIT: 7035 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7036 if ( ctxt == NULL ) { 7037 croak("XPathContext: missing xpath context\n"); 7038 } 7039 CODE: 7040 RETVAL = ctxt->contextSize; 7041 OUTPUT: 7042 RETVAL 7043 7044void 7045setContextNode( self , pnode ) 7046 SV * self 7047 SV * pnode 7048 INIT: 7049 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7050 if ( ctxt == NULL ) { 7051 croak("XPathContext: missing xpath context\n"); 7052 } 7053 PPCODE: 7054 if (XPathContextDATA(ctxt)->node != NULL) { 7055 SvREFCNT_dec(XPathContextDATA(ctxt)->node); 7056 } 7057 if (SvOK(pnode)) { 7058 XPathContextDATA(ctxt)->node = newSVsv(pnode); 7059 } else { 7060 XPathContextDATA(ctxt)->node = NULL; 7061 } 7062 7063void 7064setContextPosition( self , position ) 7065 SV * self 7066 int position 7067 INIT: 7068 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7069 if ( ctxt == NULL ) 7070 croak("XPathContext: missing xpath context\n"); 7071 if ( position < -1 || position > ctxt->contextSize ) 7072 croak("XPathContext: invalid position\n"); 7073 PPCODE: 7074 ctxt->proximityPosition = position; 7075 7076void 7077setContextSize( self , size ) 7078 SV * self 7079 int size 7080 INIT: 7081 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7082 if ( ctxt == NULL ) 7083 croak("XPathContext: missing xpath context\n"); 7084 if ( size < -1 ) 7085 croak("XPathContext: invalid size\n"); 7086 PPCODE: 7087 ctxt->contextSize = size; 7088 if ( size == 0 ) 7089 ctxt->proximityPosition = 0; 7090 else if ( size > 0 ) 7091 ctxt->proximityPosition = 1; 7092 else 7093 ctxt->proximityPosition = -1; 7094 7095void 7096registerNs( pxpath_context, prefix, ns_uri ) 7097 SV * pxpath_context 7098 SV * prefix 7099 SV * ns_uri 7100 PREINIT: 7101 xmlXPathContextPtr ctxt = NULL; 7102 INIT: 7103 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7104 if ( ctxt == NULL ) { 7105 croak("XPathContext: missing xpath context\n"); 7106 } 7107 LibXML_configure_xpathcontext(ctxt); 7108 PPCODE: 7109 if(SvOK(ns_uri)) { 7110 if(xmlXPathRegisterNs(ctxt, (xmlChar *) SvPV_nolen(prefix), 7111 (xmlChar *) SvPV_nolen(ns_uri)) == -1) { 7112 croak("XPathContext: cannot register namespace\n"); 7113 } 7114 } else { 7115 if(xmlXPathRegisterNs(ctxt, (xmlChar *) SvPV_nolen(prefix), NULL) == -1) { 7116 croak("XPathContext: cannot unregister namespace\n"); 7117 } 7118 } 7119 7120SV* 7121lookupNs( pxpath_context, prefix ) 7122 SV * pxpath_context 7123 SV * prefix 7124 PREINIT: 7125 xmlXPathContextPtr ctxt = NULL; 7126 INIT: 7127 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7128 if ( ctxt == NULL ) { 7129 croak("XPathContext: missing xpath context\n"); 7130 } 7131 LibXML_configure_xpathcontext(ctxt); 7132 CODE: 7133 RETVAL = C2Sv(xmlXPathNsLookup(ctxt, (xmlChar *) SvPV_nolen(prefix)), NULL); 7134 OUTPUT: 7135 RETVAL 7136 7137SV* 7138getVarLookupData( self ) 7139 SV * self 7140 INIT: 7141 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7142 if ( ctxt == NULL ) { 7143 croak("XPathContext: missing xpath context\n"); 7144 } 7145 CODE: 7146 if(XPathContextDATA(ctxt)->varData != NULL) { 7147 RETVAL = newSVsv(XPathContextDATA(ctxt)->varData); 7148 } else { 7149 RETVAL = &PL_sv_undef; 7150 } 7151 OUTPUT: 7152 RETVAL 7153 7154SV* 7155getVarLookupFunc( self ) 7156 SV * self 7157 INIT: 7158 xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); 7159 if ( ctxt == NULL ) { 7160 croak("XPathContext: missing xpath context\n"); 7161 } 7162 CODE: 7163 if(XPathContextDATA(ctxt)->varData != NULL) { 7164 RETVAL = newSVsv(XPathContextDATA(ctxt)->varLookup); 7165 } else { 7166 RETVAL = &PL_sv_undef; 7167 } 7168 OUTPUT: 7169 RETVAL 7170 7171void 7172registerVarLookupFunc( pxpath_context, lookup_func, lookup_data ) 7173 SV * pxpath_context 7174 SV * lookup_func 7175 SV * lookup_data 7176 PREINIT: 7177 xmlXPathContextPtr ctxt = NULL; 7178 XPathContextDataPtr data = NULL; 7179 INIT: 7180 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7181 if ( ctxt == NULL ) 7182 croak("XPathContext: missing xpath context\n"); 7183 data = XPathContextDATA(ctxt); 7184 if ( data == NULL ) 7185 croak("XPathContext: missing xpath context private data\n"); 7186 LibXML_configure_xpathcontext(ctxt); 7187 /* free previous lookup function and data */ 7188 if (data->varLookup && SvOK(data->varLookup)) 7189 SvREFCNT_dec(data->varLookup); 7190 if (data->varData && SvOK(data->varData)) 7191 SvREFCNT_dec(data->varData); 7192 data->varLookup=NULL; 7193 data->varData=NULL; 7194 PPCODE: 7195 if (SvOK(lookup_func)) { 7196 if ( SvROK(lookup_func) && SvTYPE(SvRV(lookup_func)) == SVt_PVCV ) { 7197 data->varLookup = newSVsv(lookup_func); 7198 if (SvOK(lookup_data)) 7199 data->varData = newSVsv(lookup_data); 7200 xmlXPathRegisterVariableLookup(ctxt, 7201 LibXML_generic_variable_lookup, ctxt); 7202 if (ctxt->varLookupData==NULL || ctxt->varLookupData != ctxt) { 7203 croak( "XPathContext: registration failure\n" ); 7204 } 7205 } else { 7206 croak("XPathContext: 1st argument is not a CODE reference\n"); 7207 } 7208 } else { 7209 /* unregister */ 7210 xmlXPathRegisterVariableLookup(ctxt, NULL, NULL); 7211 } 7212 7213void 7214registerFunctionNS( pxpath_context, name, uri, func) 7215 SV * pxpath_context 7216 char * name 7217 SV * uri 7218 SV * func 7219 PREINIT: 7220 xmlXPathContextPtr ctxt = NULL; 7221 SV * pfdr; 7222 SV * key; 7223 STRLEN len; 7224 char *strkey; 7225 7226 INIT: 7227 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7228 if ( ctxt == NULL ) { 7229 croak("XPathContext: missing xpath context\n"); 7230 } 7231 LibXML_configure_xpathcontext(ctxt); 7232 if ( !SvOK(func) || 7233 (SvOK(func) && ((SvROK(func) && SvTYPE(SvRV(func)) == SVt_PVCV ) 7234 || SvPOK(func)))) { 7235 if (ctxt->funcLookupData == NULL) { 7236 if (SvOK(func)) { 7237 pfdr = newRV_inc((SV*) newHV()); 7238 ctxt->funcLookupData = pfdr; 7239 } else { 7240 /* looks like no perl function was never registered, */ 7241 /* nothing to unregister */ 7242 warn("XPathContext: nothing to unregister\n"); 7243 return; 7244 } 7245 } else { 7246 if (SvTYPE(SvRV((SV *)ctxt->funcLookupData)) == SVt_PVHV) { 7247 /* good, it's a HV */ 7248 pfdr = (SV *)ctxt->funcLookupData; 7249 } else { 7250 croak ("XPathContext: cannot register: funcLookupData structure occupied\n"); 7251 } 7252 } 7253 key = newSVpvn("",0); 7254 if (SvOK(uri)) { 7255 sv_catpv(key, "{"); 7256 sv_catsv(key, uri); 7257 sv_catpv(key, "}"); 7258 } 7259 sv_catpv(key, (const char*)name); 7260 strkey = SvPV(key, len); 7261 /* warn("Trying to store function '%s' in %d\n", strkey, pfdr); */ 7262 if (SvOK(func)) { 7263 hv_store((HV *)SvRV(pfdr),strkey, len, newSVsv(func), 0); 7264 } else { 7265 /* unregister */ 7266 hv_delete((HV *)SvRV(pfdr),strkey, len, G_DISCARD); 7267 } 7268 SvREFCNT_dec(key); 7269 } else { 7270 croak("XPathContext: 3rd argument is not a CODE reference or function name\n"); 7271 } 7272 PPCODE: 7273 if (SvOK(uri)) { 7274 xmlXPathRegisterFuncNS(ctxt, (xmlChar *) name, 7275 (xmlChar *) SvPV(uri, len), 7276 (SvOK(func) ? 7277 LibXML_generic_extension_function : NULL)); 7278 } else { 7279 xmlXPathRegisterFunc(ctxt, (xmlChar *) name, 7280 (SvOK(func) ? 7281 LibXML_generic_extension_function : NULL)); 7282 } 7283 7284void 7285_free_node_pool( pxpath_context ) 7286 SV * pxpath_context 7287 PREINIT: 7288 xmlXPathContextPtr ctxt = NULL; 7289 INIT: 7290 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7291 if ( ctxt == NULL ) { 7292 croak("XPathContext: missing xpath context\n"); 7293 } 7294 PPCODE: 7295 if (XPathContextDATA(ctxt)->pool != NULL) { 7296 SvREFCNT_dec((SV *)XPathContextDATA(ctxt)->pool); 7297 XPathContextDATA(ctxt)->pool = NULL; 7298 } 7299 7300void 7301_findnodes( pxpath_context, perl_xpath ) 7302 SV * pxpath_context 7303 SV * perl_xpath 7304 SV * saved_error = sv_2mortal(newSVpv("",0)); 7305 PREINIT: 7306 xmlXPathContextPtr ctxt = NULL; 7307 ProxyNodePtr owner = NULL; 7308 xmlXPathObjectPtr found = NULL; 7309 xmlNodeSetPtr nodelist = NULL; 7310 SV * element = NULL ; 7311 STRLEN len = 0 ; 7312 xmlChar * xpath = NULL; 7313 INIT: 7314 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7315 if ( ctxt == NULL ) { 7316 croak("XPathContext: missing xpath context\n"); 7317 } 7318 LibXML_configure_xpathcontext(ctxt); 7319 if ( ctxt->node == NULL ) { 7320 croak("XPathContext: lost current node\n"); 7321 } 7322 xpath = nodeSv2C(perl_xpath, ctxt->node); 7323 if ( !(xpath && xmlStrlen(xpath)) ) { 7324 if ( xpath ) 7325 xmlFree(xpath); 7326 croak("XPathContext: empty XPath found\n"); 7327 XSRETURN_UNDEF; 7328 } 7329 PPCODE: 7330 if ( ctxt->node->doc ) { 7331 domNodeNormalize( xmlDocGetRootElement(ctxt->node->doc) ); 7332 } 7333 else { 7334 domNodeNormalize( PmmOWNER(PmmNewNode(ctxt->node)) ); 7335 } 7336 7337 LibXML_init_error_ctx(saved_error); 7338 7339 PUTBACK ; 7340 found = domXPathFindCtxt( ctxt, xpath ); 7341 SPAGAIN ; 7342 7343 if (found != NULL) { 7344 nodelist = found->nodesetval; 7345 } else { 7346 nodelist = NULL; 7347 } 7348 xmlFree(xpath); 7349 7350 if ( nodelist ) { 7351 if ( nodelist->nodeNr > 0 ) { 7352 int i; 7353 const char * cls = "XML::LibXML::Node"; 7354 xmlNodePtr tnode; 7355 len = nodelist->nodeNr; 7356 for( i = 0 ; i < len; i++){ 7357 /* we have to create a new instance of an objectptr. 7358 * and then place the current node into the new object. 7359 * afterwards we can push the object to the array! 7360 */ 7361 element = NULL; 7362 tnode = nodelist->nodeTab[i]; 7363 if (tnode->type == XML_NAMESPACE_DECL) { 7364 xmlNsPtr newns = xmlCopyNamespace((xmlNsPtr)tnode); 7365 if ( newns != NULL ) { 7366 element = NEWSV(0,0); 7367 cls = PmmNodeTypeName( tnode ); 7368 element = sv_setref_pv( element, 7369 (const char *)cls, 7370 newns 7371 ); 7372 } 7373 else { 7374 continue; 7375 } 7376 } 7377 else { 7378 if (tnode->doc) { 7379 owner = PmmOWNERPO(PmmNewNode((xmlNodePtr) tnode->doc)); 7380 } else { 7381 owner = NULL; /* self contained node */ 7382 } 7383 element = PmmNodeToSv(tnode, owner); 7384 } 7385 XPUSHs( sv_2mortal(element) ); 7386 } 7387 } 7388 /* prevent libxml2 from freeing the actual nodes */ 7389 if (found->boolval) found->boolval=0; 7390 xmlXPathFreeObject(found); 7391 LibXML_report_error_ctx(saved_error, 1); 7392 } 7393 else { 7394 xmlXPathFreeObject(found); 7395 LibXML_report_error_ctx(saved_error, 0); 7396 } 7397 7398void 7399_find( pxpath_context, pxpath ) 7400 SV * pxpath_context 7401 SV * pxpath 7402 PREINIT: 7403 xmlXPathContextPtr ctxt = NULL; 7404 ProxyNodePtr owner = NULL; 7405 xmlXPathObjectPtr found = NULL; 7406 xmlNodeSetPtr nodelist = NULL; 7407 STRLEN len = 0 ; 7408 xmlChar * xpath = NULL; 7409 SV * saved_error = sv_2mortal(newSVpv("",0)); 7410 INIT: 7411 ctxt = (xmlXPathContextPtr)SvIV(SvRV(pxpath_context)); 7412 if ( ctxt == NULL ) { 7413 croak("XPathContext: missing xpath context\n"); 7414 } 7415 LibXML_configure_xpathcontext(ctxt); 7416 if ( ctxt->node == NULL ) { 7417 croak("XPathContext: lost current node\n"); 7418 } 7419 xpath = nodeSv2C(pxpath, ctxt->node); 7420 if ( !(xpath && xmlStrlen(xpath)) ) { 7421 if ( xpath ) 7422 xmlFree(xpath); 7423 croak("XPathContext: empty XPath found\n"); 7424 XSRETURN_UNDEF; 7425 } 7426 7427 PPCODE: 7428 if ( ctxt->node->doc ) { 7429 domNodeNormalize( xmlDocGetRootElement( ctxt->node->doc ) ); 7430 } 7431 else { 7432 domNodeNormalize( PmmOWNER(PmmNewNode(ctxt->node)) ); 7433 } 7434 7435 LibXML_init_error_ctx(saved_error); 7436 7437 PUTBACK ; 7438 found = domXPathFindCtxt( ctxt, xpath ); 7439 SPAGAIN ; 7440 7441 xmlFree( xpath ); 7442 7443 if (found) { 7444 switch (found->type) { 7445 case XPATH_NODESET: 7446 /* return as a NodeList */ 7447 /* access ->nodesetval */ 7448 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::NodeList", 0))); 7449 nodelist = found->nodesetval; 7450 if ( nodelist ) { 7451 if ( nodelist->nodeNr > 0 ) { 7452 int i; 7453 const char * cls = "XML::LibXML::Node"; 7454 xmlNodePtr tnode; 7455 SV * element; 7456 7457 len = nodelist->nodeNr; 7458 for( i = 0 ; i < len; i++){ 7459 /* we have to create a new instance of an 7460 * objectptr. and then 7461 * place the current node into the new 7462 * object. afterwards we can 7463 * push the object to the array! 7464 */ 7465 tnode = nodelist->nodeTab[i]; 7466 7467 /* let's be paranoid */ 7468 if (tnode->type == XML_NAMESPACE_DECL) { 7469 xmlNsPtr newns = xmlCopyNamespace((xmlNsPtr)tnode); 7470 if ( newns != NULL ) { 7471 element = NEWSV(0,0); 7472 cls = PmmNodeTypeName( tnode ); 7473 element = sv_setref_pv( element, 7474 (const char *)cls, 7475 (void*)newns 7476 ); 7477 } 7478 else { 7479 continue; 7480 } 7481 } 7482 else { 7483 if (tnode->doc) { 7484 owner = PmmOWNERPO(PmmNewNode((xmlNodePtr) tnode->doc)); 7485 } else { 7486 owner = NULL; /* self contained node */ 7487 } 7488 element = PmmNodeToSv(tnode, owner); 7489 } 7490 XPUSHs( sv_2mortal(element) ); 7491 } 7492 } 7493 } 7494 /* prevent libxml2 from freeing the actual nodes */ 7495 if (found->boolval) found->boolval=0; 7496 break; 7497 case XPATH_BOOLEAN: 7498 /* return as a Boolean */ 7499 /* access ->boolval */ 7500 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Boolean", 0))); 7501 XPUSHs(sv_2mortal(newSViv(found->boolval))); 7502 break; 7503 case XPATH_NUMBER: 7504 /* return as a Number */ 7505 /* access ->floatval */ 7506 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Number", 0))); 7507 XPUSHs(sv_2mortal(newSVnv(found->floatval))); 7508 break; 7509 case XPATH_STRING: 7510 /* access ->stringval */ 7511 /* return as a Literal */ 7512 XPUSHs(sv_2mortal(newSVpv("XML::LibXML::Literal", 0))); 7513 XPUSHs(sv_2mortal(C2Sv(found->stringval, NULL))); 7514 break; 7515 default: 7516 croak("Unknown XPath return type"); 7517 } 7518 xmlXPathFreeObject(found); 7519 LibXML_report_error_ctx(saved_error, 1); 7520 } 7521 else { 7522 LibXML_report_error_ctx(saved_error, 0); 7523 } 7524 7525MODULE = XML::LibXML PACKAGE = XML::LibXML::InputCallback 7526 7527void 7528lib_cleanup_callbacks( self ) 7529 SV * self 7530 CODE: 7531 xmlCleanupInputCallbacks(); 7532 xmlRegisterDefaultInputCallbacks(); 7533 7534void 7535lib_init_callbacks( self ) 7536 SV * self 7537 CODE: 7538 xmlRegisterDefaultInputCallbacks(); /* important */ 7539 xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXML_input_match, 7540 (xmlInputOpenCallback) LibXML_input_open, 7541 (xmlInputReadCallback) LibXML_input_read, 7542 (xmlInputCloseCallback) LibXML_input_close); 7543 7544#ifdef HAVE_READER_SUPPORT 7545 7546MODULE = XML::LibXML PACKAGE = XML::LibXML::Reader 7547 7548xmlTextReaderPtr 7549_newForFile(CLASS, filename, encoding, options) 7550 const char* CLASS 7551 const char* filename 7552 const char * encoding = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7553 int options = SvOK($arg) ? SvIV($arg) : 0; 7554 CODE: 7555 RETVAL = xmlReaderForFile(filename, encoding, options); 7556 if (RETVAL) { 7557 xmlTextReaderSetErrorHandler(RETVAL, LibXML_reader_error_handler,newSVpv("",0)); 7558 } 7559 OUTPUT: 7560 RETVAL 7561 7562xmlTextReaderPtr 7563_newForIO(CLASS, fh, url, encoding, options) 7564 const char* CLASS 7565 SV * fh 7566 const char * url = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7567 const char * encoding = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7568 int options = SvOK($arg) ? SvIV($arg) : 0; 7569 CODE: 7570 SvREFCNT_inc(fh); /* _dec'd by LibXML_close_perl */ 7571 RETVAL = xmlReaderForIO((xmlInputReadCallback) LibXML_read_perl, 7572 (xmlInputCloseCallback) LibXML_close_perl, 7573 (void *) fh, url, encoding, options); 7574 if (RETVAL) { 7575 xmlTextReaderSetErrorHandler(RETVAL, LibXML_reader_error_handler,newSVpv("",0)); 7576 } 7577 OUTPUT: 7578 RETVAL 7579 7580xmlTextReaderPtr 7581_newForString(CLASS, string, url, encoding, options) 7582 const char* CLASS 7583 SV * string 7584 const char * url = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7585 const char * encoding = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7586 int options = SvOK($arg) ? SvIV($arg) : 0; 7587 CODE: 7588 if (encoding == NULL && SvUTF8( string )) { 7589 encoding = "UTF-8"; 7590 } 7591 RETVAL = xmlReaderForDoc((xmlChar* )SvPV_nolen(string), url, encoding, options); 7592 if (RETVAL) { 7593 xmlTextReaderSetErrorHandler(RETVAL, LibXML_reader_error_handler,newSVpv("",0)); 7594 } 7595 OUTPUT: 7596 RETVAL 7597 7598xmlTextReaderPtr 7599_newForFd(CLASS, fd, url, encoding, options) 7600 const char* CLASS 7601 int fd 7602 const char * url = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7603 const char * encoding = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7604 int options = SvOK($arg) ? SvIV($arg) : 0; 7605 CODE: 7606 RETVAL = xmlReaderForFd(fd, url, encoding, options); 7607 if (RETVAL) { 7608 xmlTextReaderSetErrorHandler(RETVAL, LibXML_reader_error_handler,newSVpv("",0)); 7609 } 7610 OUTPUT: 7611 RETVAL 7612 7613xmlTextReaderPtr 7614_newForDOM(CLASS, perl_doc) 7615 const char* CLASS 7616 SV * perl_doc 7617 CODE: 7618 PmmREFCNT_inc(SvPROXYNODE(perl_doc)); /* _dec in DESTROY */ 7619 RETVAL = xmlReaderWalker((xmlDocPtr) PmmSvNode(perl_doc)); 7620 OUTPUT: 7621 RETVAL 7622 7623int 7624attributeCount(reader) 7625 xmlTextReaderPtr reader 7626 CODE: 7627 RETVAL = xmlTextReaderAttributeCount(reader); 7628 OUTPUT: 7629 RETVAL 7630 7631SV * 7632baseURI(reader) 7633 xmlTextReaderPtr reader 7634 PREINIT: 7635 const xmlChar *result = NULL; 7636 CODE: 7637 result = xmlTextReaderConstBaseUri(reader); 7638 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7639 OUTPUT: 7640 RETVAL 7641 7642int 7643byteConsumed(reader) 7644 xmlTextReaderPtr reader 7645 CODE: 7646 RETVAL = xmlTextReaderByteConsumed(reader); 7647 OUTPUT: 7648 RETVAL 7649 7650int 7651_close(reader) 7652 xmlTextReaderPtr reader 7653 CODE: 7654 RETVAL = xmlTextReaderClose(reader); 7655 OUTPUT: 7656 RETVAL 7657 7658SV * 7659encoding(reader) 7660 xmlTextReaderPtr reader 7661 PREINIT: 7662 const xmlChar *result = NULL; 7663 CODE: 7664 result = xmlTextReaderConstEncoding(reader); 7665 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7666 OUTPUT: 7667 RETVAL 7668 7669SV * 7670localName(reader) 7671 xmlTextReaderPtr reader 7672 PREINIT: 7673 const xmlChar *result = NULL; 7674 CODE: 7675 result = xmlTextReaderConstLocalName(reader); 7676 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7677 OUTPUT: 7678 RETVAL 7679 7680SV * 7681name(reader) 7682 xmlTextReaderPtr reader 7683 PREINIT: 7684 const xmlChar *result = NULL; 7685 CODE: 7686 result = xmlTextReaderConstName(reader); 7687 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7688 OUTPUT: 7689 RETVAL 7690 7691SV * 7692namespaceURI(reader) 7693 xmlTextReaderPtr reader 7694 PREINIT: 7695 const xmlChar *result = NULL; 7696 CODE: 7697 result = xmlTextReaderConstNamespaceUri(reader); 7698 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7699 OUTPUT: 7700 RETVAL 7701 7702SV * 7703prefix(reader) 7704 xmlTextReaderPtr reader 7705 PREINIT: 7706 const xmlChar *result = NULL; 7707 CODE: 7708 result = xmlTextReaderConstPrefix(reader); 7709 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7710 OUTPUT: 7711 RETVAL 7712 7713SV * 7714value(reader) 7715 xmlTextReaderPtr reader 7716 PREINIT: 7717 const xmlChar *result = NULL; 7718 CODE: 7719 result = xmlTextReaderConstValue(reader); 7720 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7721 OUTPUT: 7722 RETVAL 7723 7724SV * 7725xmlLang(reader) 7726 xmlTextReaderPtr reader 7727 PREINIT: 7728 const xmlChar *result = NULL; 7729 CODE: 7730 result = xmlTextReaderConstXmlLang(reader); 7731 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7732 OUTPUT: 7733 RETVAL 7734 7735 7736SV * 7737xmlVersion(reader) 7738 xmlTextReaderPtr reader 7739 PREINIT: 7740 const xmlChar *result = NULL; 7741 CODE: 7742 result = xmlTextReaderConstXmlVersion(reader); 7743 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7744 OUTPUT: 7745 RETVAL 7746 7747 7748int 7749depth(reader) 7750 xmlTextReaderPtr reader 7751 CODE: 7752 RETVAL = xmlTextReaderDepth(reader); 7753 OUTPUT: 7754 RETVAL 7755 7756 7757SV * 7758getAttribute(reader, name) 7759 xmlTextReaderPtr reader 7760 char * name 7761 PREINIT: 7762 xmlChar *result = NULL; 7763 CODE: 7764 result = xmlTextReaderGetAttribute(reader, (xmlChar*) name); 7765 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7766 xmlFree(result); 7767 OUTPUT: 7768 RETVAL 7769 7770SV * 7771getAttributeNo(reader, no) 7772 xmlTextReaderPtr reader 7773 int no 7774 PREINIT: 7775 xmlChar *result = NULL; 7776 CODE: 7777 result = xmlTextReaderGetAttributeNo(reader, no); 7778 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7779 xmlFree(result); 7780 OUTPUT: 7781 RETVAL 7782 7783SV * 7784getAttributeNs(reader, localName, namespaceURI) 7785 xmlTextReaderPtr reader 7786 char * localName 7787 char * namespaceURI = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7788 PREINIT: 7789 xmlChar *result = NULL; 7790 CODE: 7791 result = xmlTextReaderGetAttributeNs(reader, (xmlChar*) localName, 7792 (xmlChar*) namespaceURI); 7793 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7794 xmlFree(result); 7795 OUTPUT: 7796 RETVAL 7797 7798int 7799columnNumber(reader) 7800 xmlTextReaderPtr reader 7801 CODE: 7802 RETVAL = xmlTextReaderGetParserColumnNumber(reader); 7803 OUTPUT: 7804 RETVAL 7805 7806int 7807lineNumber(reader) 7808 xmlTextReaderPtr reader 7809 CODE: 7810 RETVAL = xmlTextReaderGetParserLineNumber(reader); 7811 OUTPUT: 7812 RETVAL 7813 7814int 7815_getParserProp(reader, prop) 7816 xmlTextReaderPtr reader 7817 int prop 7818 CODE: 7819 RETVAL = xmlTextReaderGetParserProp(reader, prop); 7820 OUTPUT: 7821 RETVAL 7822 7823int 7824hasAttributes(reader) 7825 xmlTextReaderPtr reader 7826 CODE: 7827 RETVAL = xmlTextReaderHasAttributes(reader); 7828 OUTPUT: 7829 RETVAL 7830 7831int 7832hasValue(reader) 7833 xmlTextReaderPtr reader 7834 CODE: 7835 RETVAL = xmlTextReaderHasValue(reader); 7836 OUTPUT: 7837 RETVAL 7838 7839int 7840isDefault(reader) 7841 xmlTextReaderPtr reader 7842 CODE: 7843 RETVAL = xmlTextReaderIsDefault(reader); 7844 OUTPUT: 7845 RETVAL 7846 7847int 7848isEmptyElement(reader) 7849 xmlTextReaderPtr reader 7850 CODE: 7851 RETVAL = xmlTextReaderIsEmptyElement(reader); 7852 OUTPUT: 7853 RETVAL 7854 7855int 7856isNamespaceDecl(reader) 7857 xmlTextReaderPtr reader 7858 CODE: 7859 RETVAL = xmlTextReaderIsNamespaceDecl(reader); 7860 OUTPUT: 7861 RETVAL 7862 7863int 7864isValid(reader) 7865 xmlTextReaderPtr reader 7866 CODE: 7867 RETVAL = xmlTextReaderIsValid(reader); 7868 OUTPUT: 7869 RETVAL 7870 7871SV * 7872lookupNamespace(reader, prefix) 7873 xmlTextReaderPtr reader 7874 char * prefix = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7875 PREINIT: 7876 xmlChar *result = NULL; 7877 CODE: 7878 result = xmlTextReaderLookupNamespace(reader, (xmlChar*) prefix); 7879 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 7880 xmlFree(result); 7881 OUTPUT: 7882 RETVAL 7883 7884 7885int 7886moveToAttribute(reader, name) 7887 xmlTextReaderPtr reader 7888 char * name 7889 CODE: 7890 RETVAL = xmlTextReaderMoveToAttribute(reader, (xmlChar*) name); 7891 OUTPUT: 7892 RETVAL 7893 7894int 7895moveToAttributeNo(reader, no) 7896 xmlTextReaderPtr reader 7897 int no 7898 CODE: 7899 RETVAL = xmlTextReaderMoveToAttributeNo(reader, no); 7900 OUTPUT: 7901 RETVAL 7902 7903int 7904moveToAttributeNs(reader, localName, namespaceURI) 7905 xmlTextReaderPtr reader 7906 char * localName 7907 char * namespaceURI = SvOK($arg) ? SvPV_nolen($arg) : NULL; 7908 CODE: 7909 RETVAL = xmlTextReaderMoveToAttributeNs(reader, 7910 (xmlChar*) localName, (xmlChar*) namespaceURI); 7911 OUTPUT: 7912 RETVAL 7913 7914int 7915moveToElement(reader) 7916 xmlTextReaderPtr reader 7917 CODE: 7918 RETVAL = xmlTextReaderMoveToElement(reader); 7919 OUTPUT: 7920 RETVAL 7921 7922int 7923moveToFirstAttribute(reader) 7924 xmlTextReaderPtr reader 7925 CODE: 7926 RETVAL = xmlTextReaderMoveToFirstAttribute(reader); 7927 OUTPUT: 7928 RETVAL 7929 7930int 7931moveToNextAttribute(reader) 7932 xmlTextReaderPtr reader 7933 CODE: 7934 RETVAL = xmlTextReaderMoveToNextAttribute(reader); 7935 OUTPUT: 7936 RETVAL 7937 7938int 7939next(reader) 7940 xmlTextReaderPtr reader 7941 CODE: 7942 RETVAL = xmlTextReaderNext(reader); 7943 LibXML_report_reader_error(reader); 7944 OUTPUT: 7945 RETVAL 7946 7947#define LIBXML_READER_NEXT_SIBLING(ret,reader) \ 7948 ret = xmlTextReaderNextSibling(reader); \ 7949 if (ret == -1) \ 7950 { \ 7951 int depth; \ 7952 depth = xmlTextReaderDepth(reader); \ 7953 ret = xmlTextReaderRead(reader); \ 7954 while (ret == 1 && xmlTextReaderDepth(reader) > depth) { \ 7955 ret = xmlTextReaderNext(reader); \ 7956 } \ 7957 if (ret == 1) { \ 7958 if (xmlTextReaderDepth(reader) != depth) { \ 7959 ret = 0; \ 7960 } else if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { \ 7961 ret = xmlTextReaderRead(reader); \ 7962 } \ 7963 } \ 7964 } 7965 7966int 7967nextSibling(reader) 7968 xmlTextReaderPtr reader 7969 CODE: 7970 LIBXML_READER_NEXT_SIBLING(RETVAL,reader) 7971 LibXML_report_reader_error(reader); 7972 OUTPUT: 7973 RETVAL 7974 7975int 7976nextSiblingElement(reader, name = NULL, nsURI = NULL) 7977 xmlTextReaderPtr reader 7978 const char * name 7979 const char * nsURI 7980 CODE: 7981 do { 7982 LIBXML_READER_NEXT_SIBLING(RETVAL,reader) 7983 if (LIBXML_READER_TEST_ELEMENT(reader,name,nsURI)) { 7984 break; 7985 } 7986 } while (RETVAL == 1); 7987 LibXML_report_reader_error(reader); 7988 OUTPUT: 7989 RETVAL 7990 7991int 7992nextElement(reader, name = NULL, nsURI = NULL) 7993 xmlTextReaderPtr reader 7994 const char * name 7995 const char * nsURI 7996 CODE: 7997 do { 7998 RETVAL = xmlTextReaderRead(reader); 7999 if (LIBXML_READER_TEST_ELEMENT(reader,name,nsURI)) { 8000 break; 8001 } 8002 } while (RETVAL == 1); 8003 LibXML_report_reader_error(reader); 8004 OUTPUT: 8005 RETVAL 8006 8007int 8008skipSiblings(reader) 8009 xmlTextReaderPtr reader 8010 PREINIT: 8011 int depth; 8012 CODE: 8013 depth = xmlTextReaderDepth(reader); 8014 RETVAL = -1; 8015 if (depth > 0) { 8016 do { 8017 RETVAL = xmlTextReaderNext(reader); 8018 } while (RETVAL == 1 && xmlTextReaderDepth(reader) >= depth); 8019 if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT) { 8020 RETVAL = -1; 8021 } 8022 } 8023 LibXML_report_reader_error(reader); 8024 OUTPUT: 8025 RETVAL 8026 8027int 8028nodeType(reader) 8029 xmlTextReaderPtr reader 8030 CODE: 8031 RETVAL = xmlTextReaderNodeType(reader); 8032 OUTPUT: 8033 RETVAL 8034 8035SV* 8036quoteChar(reader) 8037 xmlTextReaderPtr reader 8038 PREINIT: 8039 int ret; 8040 CODE: 8041 ret = xmlTextReaderQuoteChar(reader); 8042 if (ret == -1) XSRETURN_UNDEF; 8043 RETVAL = newSVpvf("%c",ret); 8044 OUTPUT: 8045 RETVAL 8046 8047int 8048read(reader) 8049 xmlTextReaderPtr reader 8050 CODE: 8051 RETVAL = xmlTextReaderRead(reader); 8052 LibXML_report_reader_error(reader); 8053 OUTPUT: 8054 RETVAL 8055 8056int 8057readAttributeValue(reader) 8058 xmlTextReaderPtr reader 8059 CODE: 8060 RETVAL = xmlTextReaderReadAttributeValue(reader); 8061 LibXML_report_reader_error(reader); 8062 OUTPUT: 8063 RETVAL 8064 8065 8066SV * 8067readInnerXml(reader) 8068 xmlTextReaderPtr reader 8069 PREINIT: 8070 xmlChar *result = NULL; 8071 CODE: 8072 result = xmlTextReaderReadInnerXml(reader); 8073 if (!result) XSRETURN_UNDEF; 8074 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 8075 LibXML_report_reader_error(reader); 8076 xmlFree(result); 8077 OUTPUT: 8078 RETVAL 8079 8080SV * 8081readOuterXml(reader) 8082 xmlTextReaderPtr reader 8083 PREINIT: 8084 xmlChar *result = NULL; 8085 CODE: 8086 result = xmlTextReaderReadOuterXml(reader); 8087 if (!result) XSRETURN_UNDEF; 8088 RETVAL = C2Sv(result, xmlTextReaderConstEncoding(reader)); 8089 xmlFree(result); 8090 LibXML_report_reader_error(reader); 8091 OUTPUT: 8092 RETVAL 8093 8094int 8095readState(reader) 8096 xmlTextReaderPtr reader 8097 CODE: 8098 RETVAL = xmlTextReaderReadState(reader); 8099 OUTPUT: 8100 RETVAL 8101 8102int 8103_setParserProp(reader, prop, value) 8104 xmlTextReaderPtr reader 8105 int prop 8106 int value 8107 CODE: 8108 RETVAL = xmlTextReaderSetParserProp(reader, prop, value); 8109 OUTPUT: 8110 RETVAL 8111 8112int 8113standalone(reader) 8114 xmlTextReaderPtr reader 8115 CODE: 8116 RETVAL = xmlTextReaderStandalone(reader); 8117 OUTPUT: 8118 RETVAL 8119 8120SV * 8121copyCurrentNode(reader,expand = 0) 8122 xmlTextReaderPtr reader 8123 int expand 8124 PREINIT: 8125 xmlNodePtr node = NULL; 8126 xmlNodePtr copy; 8127 xmlDocPtr doc; 8128 SV * perl_doc; 8129 CODE: 8130 if (expand) { 8131 node = xmlTextReaderExpand(reader); 8132 } 8133 else { 8134 node = xmlTextReaderCurrentNode(reader); 8135 } 8136 LibXML_report_reader_error(reader); 8137 if (!node) XSRETURN_UNDEF; 8138 8139 doc = xmlTextReaderCurrentDoc(reader); 8140 if (!doc) XSRETURN_UNDEF; 8141 perl_doc = PmmNodeToSv((xmlNodePtr)doc, NULL); 8142 if ( PmmREFCNT(SvPROXYNODE(perl_doc))==1 ) { 8143 /* will be decremented in Reader destructor */ 8144 PmmREFCNT_inc(SvPROXYNODE(perl_doc)); 8145 } 8146 8147 copy = PmmCloneNode( node, expand ); 8148 if ( copy == NULL ) { 8149 XSRETURN_UNDEF; 8150 } 8151 if ( copy->type == XML_DTD_NODE ) { 8152 RETVAL = PmmNodeToSv(copy, NULL); 8153 } 8154 else { 8155 ProxyNodePtr docfrag = NULL; 8156 8157 if ( doc != NULL ) { 8158 xmlSetTreeDoc(copy, doc); 8159 } 8160 docfrag = PmmNewFragment( doc ); 8161 xmlAddChild( PmmNODE(docfrag), copy ); 8162 RETVAL = PmmNodeToSv(copy, docfrag); 8163 } 8164 OUTPUT: 8165 RETVAL 8166 8167SV * 8168document(reader) 8169 xmlTextReaderPtr reader 8170 PREINIT: 8171 xmlDocPtr doc = NULL; 8172 CODE: 8173 doc = xmlTextReaderCurrentDoc(reader); 8174 if (!doc) XSRETURN_UNDEF; 8175 RETVAL = PmmNodeToSv((xmlNodePtr)doc, NULL); 8176 if ( PmmREFCNT(SvPROXYNODE(RETVAL))==1 ) { 8177 /* will be decremented in Reader destructor */ 8178 PmmREFCNT_inc(SvPROXYNODE(RETVAL)); 8179 } 8180 OUTPUT: 8181 RETVAL 8182 8183int 8184_preservePattern(reader,pattern,ns_map=NULL) 8185 xmlTextReaderPtr reader 8186 char * pattern 8187 AV * ns_map 8188 PREINIT: 8189 xmlChar** namespaces = NULL; 8190 SV** aux; 8191 int last,i; 8192 CODE: 8193 if (ns_map) { 8194 last = av_len(ns_map); 8195 New(0,namespaces, last+2, xmlChar*); 8196 for( i = 0; i <= last ; i++ ) { 8197 aux = av_fetch(ns_map,i,0); 8198 namespaces[i]=(xmlChar*) SvPV_nolen(*aux); 8199 } 8200 namespaces[i]=0; 8201 } 8202 RETVAL = xmlTextReaderPreservePattern(reader,(const xmlChar*) pattern, 8203 (const xmlChar**)namespaces); 8204 Safefree(namespaces); 8205 OUTPUT: 8206 RETVAL 8207 8208SV * 8209preserveNode(reader) 8210 xmlTextReaderPtr reader 8211 PREINIT: 8212 xmlNodePtr node; 8213 xmlDocPtr doc; 8214 SV * perl_doc; 8215 CODE: 8216 doc = xmlTextReaderCurrentDoc(reader); 8217 if (!doc) XSRETURN_UNDEF; 8218 perl_doc = PmmNodeToSv((xmlNodePtr)doc, NULL); 8219 if ( PmmREFCNT(SvPROXYNODE(perl_doc))==1 ) { 8220 /* will be decremented in Reader destructor */ 8221 PmmREFCNT_inc(SvPROXYNODE(perl_doc)); 8222 } 8223 node = xmlTextReaderPreserve(reader); 8224 if (node) { 8225 RETVAL = PmmNodeToSv(node, PmmOWNERPO(PmmPROXYNODE(doc))); 8226 } else { 8227 XSRETURN_UNDEF; 8228 } 8229 OUTPUT: 8230 RETVAL 8231 8232int 8233finish(reader) 8234 xmlTextReaderPtr reader 8235 CODE: 8236 while (1) { 8237 RETVAL = xmlTextReaderRead(reader); 8238 if (RETVAL!=1) break; 8239 } 8240 LibXML_report_reader_error(reader); 8241 RETVAL++; /* we want 0 - fail, 1- success */ 8242 OUTPUT: 8243 RETVAL 8244 8245#ifdef HAVE_SCHEMAS 8246 8247int 8248_setRelaxNGFile(reader,rng) 8249 xmlTextReaderPtr reader 8250 char* rng 8251 CODE: 8252 RETVAL = xmlTextReaderRelaxNGValidate(reader,rng); 8253 OUTPUT: 8254 RETVAL 8255 8256int 8257_setRelaxNG(reader,rng_doc) 8258 xmlTextReaderPtr reader 8259 xmlRelaxNGPtr rng_doc 8260 CODE: 8261 RETVAL = xmlTextReaderRelaxNGSetSchema(reader,rng_doc); 8262 OUTPUT: 8263 RETVAL 8264 8265int 8266_setXSDFile(reader,xsd) 8267 xmlTextReaderPtr reader 8268 char* xsd 8269 CODE: 8270 RETVAL = xmlTextReaderSchemaValidate(reader,xsd); 8271 OUTPUT: 8272 RETVAL 8273 8274int 8275_setXSD(reader,xsd_doc) 8276 xmlTextReaderPtr reader 8277 xmlSchemaPtr xsd_doc 8278 CODE: 8279 RETVAL = xmlTextReaderSetSchema(reader,xsd_doc); 8280 OUTPUT: 8281 RETVAL 8282 8283#endif 8284 8285void 8286_DESTROY(reader) 8287 xmlTextReaderPtr reader 8288 PREINIT: 8289 xmlDocPtr doc; 8290 SV * perl_doc; 8291 SV * error_sv = NULL; 8292 xmlTextReaderErrorFunc f = NULL; 8293 CODE: 8294 doc = xmlTextReaderCurrentDoc(reader); 8295 if (doc) { 8296 perl_doc = PmmNodeToSv((xmlNodePtr)doc, NULL); 8297 if ( PmmREFCNT(SvPROXYNODE(perl_doc))>1 ) { 8298 /* was incremented in document() to pervent from PMM destruction */ 8299 PmmREFCNT_dec(SvPROXYNODE(perl_doc)); 8300 } 8301 SvREFCNT_dec(perl_doc); 8302 } 8303 if (xmlTextReaderReadState(reader) != XML_TEXTREADER_MODE_CLOSED) { 8304 xmlTextReaderClose(reader); 8305 } 8306 xmlTextReaderGetErrorHandler(reader, &f, (void **) &error_sv); 8307 if (error_sv) { 8308 sv_2mortal(error_sv); 8309 } 8310 xmlFreeTextReader(reader); 8311 8312#endif /* HAVE_READER_SUPPORT */ 8313