[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 # Copyright (c) 2002-2006 Graham Barr. All rights reserved. This program is 2 # free software; you can redistribute it and/or modify it under the same 3 # terms as Perl itself. 4 5 package Net::LDAP::DSML; 6 7 use strict; 8 use vars qw(@ISA $VERSION); 9 use Carp; 10 use XML::SAX::Base; 11 use Net::LDAP::Entry; 12 13 @ISA = qw(XML::SAX::Base); 14 $VERSION = "0.13"; 15 16 # OO purists will hate this :) 17 my %schema_typemap = qw( 18 attribute-type at 19 objectclass-type oc 20 ); 21 # syn 22 # mr 23 # mru 24 # dts 25 # dtc 26 # nfm 27 28 sub new { 29 my $pkg = shift; 30 my %opt = @_; 31 32 my $sax; 33 34 if ($sax = $opt{output}) { 35 unless (ref($sax) and eval { $sax->isa('XML::SAX::Base') }) { 36 require XML::SAX::Writer; 37 $sax = XML::SAX::Writer->new( Output => $sax ); 38 } 39 40 $sax = Net::LDAP::DSML::pp->new( handler => $sax ) 41 if $opt{pretty_print}; 42 } 43 else { 44 $sax = Net::LDAP::DSML::output->new; 45 } 46 47 bless { @_, handler => $sax }, $pkg; 48 } 49 50 sub start_document { 51 my ($self, $data) = @_; 52 $self->{reader} = {}; 53 } 54 55 my %start_jumptable = qw( 56 entry entry 57 attr entry_attr 58 objectclass entry_attr 59 value entry_value 60 oc-value entry_value 61 directory-schema schema 62 attribute-type schema_element 63 objectclass-type schema_element 64 name schema_name 65 object-identifier schema_value 66 syntax schema_syntax 67 description schema_value 68 equality schema_value 69 substring schema_value 70 ordering schema_value 71 attribute schema_attr 72 ); 73 74 sub start_element { 75 my ($self, $data) = @_; 76 77 (my $tag = lc $data->{Name}) =~ s/^dsml://; 78 79 my $label = $start_jumptable{$tag} or return; 80 my $state = $self->{reader}; 81 goto $label; 82 83 entry: 84 { 85 $state->{entry} = { objectName => $data->{Attributes}{'{}dn'}{Value} }; 86 return; 87 } 88 89 entry_attr: 90 { 91 my $name = $tag eq 'objectclass' ? $tag : lc $data->{Attributes}{'{}name'}{Value}; 92 $state->{attr} = $state->{attrs}{$name} 93 ||= do { 94 my $aref = []; 95 push @{$state->{entry}{attributes}}, { 96 type => $data->{Attributes}{'{}name'}{Value}, 97 vals => $aref 98 }; 99 $aref; 100 }; 101 return; 102 } 103 104 entry_value: 105 { 106 push @{$state->{attr}}, ''; 107 $state->{value} = \${$state->{attr}}[-1]; 108 $state->{encoding} = $data->{Attributes}{'{}encoding'}{Value} || ''; 109 return; 110 } 111 112 schema: 113 { 114 $state->{schema} = {}; 115 return; 116 } 117 118 schema_element: 119 { 120 my $Attrs = $data->{Attributes}; 121 my $id = $Attrs->{'{}id'}{Value}; 122 my $elem = $state->{elem} = { type => $schema_typemap{$tag} }; 123 $state->{id}{$id} = $elem if $id; 124 125 my $value; 126 127 if (defined($value = $Attrs->{"{}type"}{Value})) { 128 $elem->{lc $value} = 1; 129 } 130 131 foreach my $attr (qw( 132 single-value 133 obsolete 134 user-modification 135 )) { 136 my $value = $Attrs->{"{}$attr"}{Value}; 137 $elem->{$attr} = 1 if defined $value and $value =~ /^true$/i; 138 } 139 140 $elem->{superior} = $value 141 if defined($value = $Attrs->{"{}superior"}{Value}); 142 143 return; 144 } 145 146 schema_name: 147 { 148 my $elem = $state->{elem}; 149 push @{$elem->{name}}, ''; 150 $state->{value} = \${$elem->{name}}[-1]; 151 return; 152 } 153 154 schema_syntax: 155 { 156 my $elem = $state->{elem}; 157 my $bound = $data->{Attributes}{'{}bound'}{Value}; 158 $elem->{max_length} = $bound if defined $bound; 159 160 $elem->{$tag} = '' unless exists $elem->{$tag}; 161 $state->{value} = \$elem->{$tag}; 162 return; 163 } 164 165 schema_value: 166 { 167 my $elem = $state->{elem}; 168 $elem->{$tag} = '' unless exists $elem->{$tag}; 169 $state->{value} = \$elem->{$tag}; 170 return; 171 } 172 173 schema_attr: 174 { 175 my $Attrs = $data->{Attributes}; 176 my $required = $data->{Attributes}{'{}required'}{Value} || 'false'; 177 my $ref = $data->{Attributes}{'{}ref'}{Value} or return; 178 my $type = $required =~ /^false$/i ? 'may' : 'must'; 179 push @{$state->{elem}{$type}}, $ref; 180 return; 181 } 182 } 183 184 my %end_jumptable = qw( 185 entry entry 186 attr entry_attr 187 objectclass entry_attr 188 value value 189 oc-value value 190 syntax value 191 description value 192 equality value 193 substring value 194 ordering value 195 name value 196 object-identifier value 197 attribute-type schema_element 198 objectclass-type schema_element 199 directory-schema schema 200 ); 201 202 sub end_element { 203 my ($self, $data) = @_; 204 (my $tag = lc $data->{Name}) =~ s/^dsml://; 205 206 my $label = $end_jumptable{$tag} or return; 207 my $state = $self->{reader}; 208 goto $label; 209 210 entry: 211 { 212 my $entry = Net::LDAP::Entry->new; 213 $entry->{asn} = delete $state->{entry}; 214 if (my $handler = $self->{entry}) { 215 $handler->($entry); 216 } 217 else { 218 push @{$state->{entries}}, $entry; 219 } 220 return; 221 } 222 223 entry_attr: 224 { 225 delete $state->{attr}; 226 return; 227 } 228 229 value: 230 { 231 delete $state->{value}; 232 delete $state->{encoding}; 233 return; 234 } 235 236 schema_element: 237 { 238 my $elem = delete $state->{elem}; 239 my $oid = $elem->{oid}; 240 my $name; 241 242 if (my $aliases = $elem->{name}) { 243 $name = $elem->{name} = shift @$aliases; 244 $elem->{aliases} = $aliases if @$aliases; 245 } 246 elsif ($oid) { 247 $name = $oid; 248 } 249 else { 250 croak "Schema element without a name or object-identifier"; 251 } 252 253 $elem->{oid} ||= $name; 254 $state->{schema}{oid}{$oid} = $state->{schema}{$elem->{type}}{lc $name} = $elem; 255 256 return; 257 } 258 259 schema: 260 { 261 my $id = $state->{id}; 262 my $schema = $state->{schema}; 263 foreach my $elem (values %{$schema->{oc}}) { 264 if (my $sup = $elem->{superior}) { 265 $sup =~ /#(.*)|(.*)/; 266 if (my $ref = $id->{$+}) { 267 $elem->{superior} = $ref->{name}; 268 } 269 else { 270 $elem->{superior} = $+; 271 } 272 } 273 foreach my $mm (qw(must may)) { 274 if (my $mmref = $elem->{$mm}) { 275 my @mm = map { 276 /#(.*)|(.*)/; 277 my $ref = $id->{$+}; 278 $ref ? $ref->{name} : $+; 279 } @$mmref; 280 $elem->{$mm} = \@mm; 281 } 282 } 283 } 284 require Net::LDAP::Schema; 285 bless $schema, 'Net::LDAP::Schema'; # Naughty :-) 286 if (my $handler = $self->{schema}) { 287 $handler->($schema); 288 } 289 return; 290 } 291 292 } 293 294 sub characters { 295 my ($self, $data) = @_; 296 my $state = $self->{reader}; 297 if (my $sref = $state->{value}) { 298 $$sref = ($state->{encoding}||'') eq 'base64' 299 ? do { require MIME::Base64; MIME::Base64::decode_base64($data->{Data}) } 300 : $data->{Data}; 301 } 302 } 303 304 sub _dsml_context { 305 my ($self, $new) = @_; 306 my $context = $self->{writer}{context}; 307 my $handler = $self->{handler}; 308 309 unless ($context) { 310 $context = $self->{writer}{context} = []; 311 $handler->start_document; 312 313 $handler->xml_decl({ 314 Standalone => '', 315 Version => '1.0', 316 Encoding => 'utf-8' 317 }); 318 } 319 320 while (@$context and ($context->[-1] ne $new) and ($context->[-1] ne 'dsml' or $new eq '')) { 321 my $old = pop @$context; 322 $handler->end_element({ 323 Name => "dsml:$old", 324 LocalName => $old, 325 NamespaceURI => 'http://www.dsml.org/DSML', 326 Prefix => 'dsml' 327 }); 328 329 $handler->end_prefix_mapping({ 330 NamespaceURI => 'http://www.dsml.org/DSML', 331 Prefix => 'dsml' 332 }) if $old eq 'dsml'; 333 } 334 335 if (!$new) { 336 $handler->end_document; 337 delete $self->{writer}{context}; 338 } 339 elsif (!@$context or $context->[-1] ne $new) { 340 $self->_dsml_context('dsml') unless $new eq 'dsml' or @$context; 341 push @$context, $new; 342 my %data = ( 343 Name => "dsml:$new", 344 LocalName => $new, 345 NamespaceURI => 'http://www.dsml.org/DSML', 346 Prefix => 'dsml', 347 ); 348 349 if ($new eq 'dsml') { 350 $handler->start_prefix_mapping({ 351 NamespaceURI => 'http://www.dsml.org/DSML', 352 Prefix => 'dsml' 353 }); 354 $data{Attributes} = { 355 '{http://www.w3.org/2000/xmlns/}dsml' => { 356 Name => 'xmlns:dsml', 357 LocalName => 'dsml', 358 NamespaceURI => 'http://www.w3.org/2000/xmlns/', 359 Value => 'http://www.dsml.org/DSML', 360 Prefix => 'xmlns' 361 } 362 }; 363 } 364 $handler->start_element(\%data); 365 } 366 } 367 368 sub start_dsml { 369 my $self = shift; 370 371 $self->_dsml_context('') if $self->{writer}{context}; 372 $self->_dsml_context('dsml'); 373 } 374 375 sub end_dsml { 376 my $self = shift; 377 $self->_dsml_context('') if $self->{writer} and $self->{writer}{context}; 378 } 379 380 sub write_entry { 381 my $self = shift; 382 my $handler = $self->{handler}; 383 384 $self->_dsml_context('directory-entries'); 385 386 my %attr; 387 my %data = ( 388 NamespaceURI => 'http://www.dsml.org/DSML', 389 Prefix => 'dsml', 390 Attributes => \%attr, 391 ); 392 foreach my $entry (@_) { 393 my $asn = $entry->asn; 394 @data{qw(Name LocalName)} = qw(dsml:entry entry); 395 %attr = ( '{}dn' => { Value => $asn->{objectName}, Name => "dn"} ); 396 $handler->start_element(\%data); 397 398 foreach my $attr ( @{$asn->{attributes}} ) { 399 my $name = $attr->{type}; 400 my $is_oc = lc($name) eq "objectclass"; 401 402 if ($is_oc) { 403 @data{qw(Name LocalName)} = qw(dsml:objectclass objectclass); 404 %attr = (); 405 $handler->start_element(\%data); 406 @data{qw(Name LocalName)} = qw(dsml:oc-value oc-value); 407 } 408 else { 409 @data{qw(Name LocalName)} = qw(dsml:attr attr); 410 %attr = ( "{}name" => { Value => $name, Name => "name" } ); 411 $handler->start_element(\%data); 412 @data{qw(Name LocalName)} = qw(dsml:value value); 413 } 414 415 my %chdata; 416 foreach my $val (@{$attr->{vals}}) { 417 if ($val =~ /(^[ :]|[\x00-\x1f\x7f-\xff])/) { 418 require MIME::Base64; 419 $chdata{Data} = MIME::Base64::encode($val,""); 420 %attr = ( '{}encoding' => { Value => 'base64', Name => "encoding"} ); 421 } 422 else { 423 $chdata{Data} = $val; 424 %attr = (); 425 } 426 $handler->start_element(\%data); 427 $handler->characters(\%chdata); 428 %attr = (); 429 $handler->end_element(\%data); 430 } 431 432 @data{qw(Name LocalName)} = $is_oc 433 ? qw(dsml:objectclass objectclass) 434 : qw(dsml:attr attr); 435 %attr = (); 436 $handler->end_element(\%data); 437 } 438 439 @data{qw(Name LocalName)} = qw(dsml:entry entry); 440 %attr = (); 441 $handler->end_element(\%data); 442 } 443 } 444 445 sub write_schema { 446 my ($self, $schema) = @_; 447 my $handler = $self->{handler}; 448 449 $self->_dsml_context('dsml'); 450 my %attr; 451 my %data = ( 452 NamespaceURI => 'http://www.dsml.org/DSML', 453 Prefix => 'dsml', 454 Attributes => \%attr, 455 ); 456 @data{qw(Name LocalName)} = qw(dsml:directory-schema directory-schema); 457 $handler->start_element(\%data); 458 my %id; 459 460 foreach my $attr ($schema->all_attributes) { 461 $id{$attr->{name}} = 1; 462 %attr = ( '{}id' => { Value => "#$attr->{name}", Name => 'id'}); 463 464 if (my $sup = $attr->{superior}) { 465 my $sup_a = $schema->attribute($sup); 466 $attr{"{}superior"} = { 467 Value => "#" . ($sup_a ? $sup_a->{name} : $sup), 468 Name => 'superior' 469 }; 470 } 471 foreach my $flag (qw(obsolete single-value)) { 472 $attr{"{}$flag"} = { 473 Value => 'true', Name => $flag 474 } if $attr->{$flag}; 475 } 476 $attr{"{}user-modification"} = { 477 Value => 'false', 478 Name => 'user-modification', 479 } unless $attr->{'user-modification'}; 480 481 @data{qw(Name LocalName)} = qw(dsml:attribute-type attribute-type); 482 $handler->start_element(\%data); 483 %attr = (); 484 unless (($attr->{name} || '') eq ($attr->{oid} || '')) { 485 @data{qw(Name LocalName)} = qw(dsml:name name); 486 $handler->start_element(\%data); 487 $handler->characters({Data => $attr->{name}}); 488 $handler->end_element(\%data); 489 } 490 if (my $aliases = $attr->{aliases}) { 491 @data{qw(Name LocalName)} = qw(dsml:name name); 492 foreach my $name (@$aliases) { 493 $handler->start_element(\%data); 494 $handler->characters({Data => $name}); 495 $handler->end_element(\%data); 496 } 497 } 498 if (my $oid = $attr->{oid}) { 499 @data{qw(Name LocalName)} = ("dsml:object-identifier","object-identifier"); 500 $handler->start_element(\%data); 501 $handler->characters({Data => $oid}); 502 $handler->end_element(\%data); 503 } 504 foreach my $elem (qw( 505 description 506 equality 507 ordering 508 substring 509 )) { 510 defined(my $text = $attr->{$elem}) or next; 511 @data{qw(Name LocalName)} = ("dsml:$elem",$elem); 512 $handler->start_element(\%data); 513 $handler->characters({Data => $text}); 514 $handler->end_element(\%data); 515 } 516 if (my $syn = $attr->{syntax}) { 517 if (defined(my $bound = $attr->{max_length})) { 518 $attr{'{}bound'} = { 519 Value => $bound, 520 Name => 'bound', 521 }; 522 } 523 @data{qw(Name LocalName)} = qw(dsml:syntax syntax); 524 $handler->start_element(\%data); 525 $handler->characters({Data => $syn}); 526 $handler->end_element(\%data); 527 } 528 @data{qw(Name LocalName)} = qw(dsml:attribute-type attribute-type); 529 $handler->end_element(\%data); 530 } 531 532 foreach my $oc ($schema->all_objectclasses) { 533 my $id = $oc->{name}; 534 $id = $oc->{'object-identifier'} if $id{$id}; 535 536 %attr = ( '{}id' => { Value => "#$id", Name => 'id'}); 537 538 if (my $sup = $oc->{superior}) { 539 my $sup_a = $schema->objectclass($sup); 540 $attr{"{}superior"} = { 541 Value => "#" . ($sup_a ? $sup_a->{name} : $sup), 542 Name => 'superior' 543 }; 544 } 545 if (my $type = (grep { $oc->{$_} } qw(structural abstract auxilary))[0]) { 546 $attr{"{}type"} = { 547 Value => $type, 548 Name => 'type', 549 }; 550 } 551 if ($oc->{obsolete}) { 552 $attr{"{}type"} = { 553 Value => 'true', 554 Name => 'obsolete', 555 }; 556 } 557 558 @data{qw(Name LocalName)} = qw(dsml:objectclass-type objectclass-type); 559 $handler->start_element(\%data); 560 %attr = (); 561 562 unless (($oc->{name} || '') eq ($oc->{'object-identifier'} || '')) { 563 @data{qw(Name LocalName)} = qw(dsml:name name); 564 $handler->start_element(\%data); 565 $handler->characters({Data => $oc->{name}}); 566 $handler->end_element(\%data); 567 } 568 if (my $aliases = $oc->{aliases}) { 569 @data{qw(Name LocalName)} = qw(dsml:name name); 570 foreach my $name (@$aliases) { 571 $handler->start_element(\%data); 572 $handler->characters({Data => $name}); 573 $handler->end_element(\%data); 574 } 575 } 576 foreach my $elem (qw( 577 description 578 object-identifier 579 )) { 580 defined(my $text = $oc->{$elem}) or next; 581 @data{qw(Name LocalName)} = ("dsml:$elem",$elem); 582 $handler->start_element(\%data); 583 $handler->characters({Data => $text}); 584 $handler->end_element(\%data); 585 } 586 @data{qw(Name LocalName)} = qw(dsml:attribute attribute); 587 foreach my $mm (qw(must may)) { 588 %attr = ( 589 '{}required' => { 590 Value => ($mm eq 'must' ? 'true' : 'false'), 591 Name => 'required' 592 }, 593 '{}ref' => { 594 Name => 'ref' 595 }, 596 ); 597 my $mmref = $oc->{$mm} or next; 598 foreach my $attr (@$mmref) { 599 my $a_ref = $schema->attribute($attr); 600 $attr{'{}ref'}{Value} = $a_ref ? $a_ref->{name} : $attr; 601 $handler->start_element(\%data); 602 $handler->end_element(\%data); 603 } 604 } 605 606 @data{qw(Name LocalName)} = qw(dsml:objectclass-type objectclass-type); 607 $handler->end_element(\%data); 608 } 609 610 %attr = (); 611 @data{qw(Name LocalName)} = qw(dsml:directory-schema directory-schema); 612 $handler->end_element(\%data); 613 } 614 615 616 package Net::LDAP::DSML::pp; 617 618 sub new { 619 my $pkg = shift; 620 bless { @_ }, $pkg; 621 } 622 623 sub start_element { 624 my ($self, $data) = @_; 625 my $handler = $self->{handler}; 626 $handler->start_element($data); 627 unless ($data->{Name} =~ /^(?:dsml:)?(?: 628 value 629 |oc-value 630 |name 631 |syntax 632 |equality 633 |substring 634 |object-identifier 635 |description 636 |ordering 637 |attribute 638 )$/ix 639 ) { 640 $handler->ignorable_whitespace({Data => "\n"}); 641 } 642 } 643 644 sub end_element { 645 my $self = shift; 646 my $handler = $self->{handler}; 647 $handler->end_element(@_); 648 $handler->ignorable_whitespace({Data => "\n"}); 649 } 650 651 sub xml_decl { 652 my $self = shift; 653 my $handler = $self->{handler}; 654 $handler->xml_decl(@_); 655 $handler->ignorable_whitespace({Data => "\n"}); 656 } 657 658 use vars qw($AUTOLOAD); 659 660 sub DESTROY {} 661 662 sub AUTOLOAD { 663 (my $meth = $AUTOLOAD) =~ s/^.*:://; 664 no strict 'refs'; 665 *{$meth} = sub { shift->{handler}->$meth(@_) }; 666 goto &$meth; 667 } 668 669 package Net::LDAP::DSML::output; 670 671 sub new { bless {} } 672 673 use vars qw($AUTOLOAD); 674 675 sub DESTROY {} 676 677 sub AUTOLOAD { 678 (my $meth = $AUTOLOAD) =~ s/^.*:://; 679 require XML::SAX::Writer; 680 my $self = shift; 681 $self->{handler} = XML::SAX::Writer->new; 682 bless $self, 'Net::LDAP::DSML::pp'; 683 $self->$meth(@_); 684 } 685 686 1; 687 688 __END__ 689 690 =head1 NAME 691 692 NET::LDAP::DSML -- A DSML Writer for Net::LDAP 693 694 =head1 SYNOPSIS 695 696 For a directory entry; 697 698 use Net::LDAP; 699 use Net::LDAP::DSML; 700 use IO::File; 701 702 703 my $server = "localhost"; 704 my $file = "testdsml.xml"; 705 my $ldap = Net::LDAP->new($server); 706 707 $ldap->bind(); 708 709 710 # 711 # For file i/o 712 # 713 my $file = "testdsml.xml"; 714 715 my $io = IO::File->new($file,"w") or die ("failed to open $file as filehandle.$!\n"); 716 717 my $dsml = Net::LDAP::DSML->new(output => $io, pretty_print => 1 ) 718 or die ("DSML object creation problem using an output file.\n"); 719 # OR 720 # 721 # For file i/o 722 # 723 724 open (IO,">$file") or die("failed to open $file.$!"); 725 726 my $dsml = Net::LDAP::DSML->new(output => *IO, pretty_print => 1) 727 or die ("DSML object creation problem using an output file.\n"); 728 729 # OR 730 # 731 # For array usage. 732 # Pass a reference to an array. 733 # 734 735 my @data = (); 736 $dsml = Net::LDAP::DSML->new(output => \@data, pretty_print => 1) 737 or die ("DSML object cration problem using an output array.\n"); 738 739 740 my $mesg = $ldap->search( 741 base => 'o=airius.com', 742 scope => 'sub', 743 filter => 'ou=accounting', 744 callback => sub { 745 my ($mesg,$entry) =@_; 746 $dsml->write_entry($entry) 747 if (ref $entry eq 'Net::LDAP::Entry'); 748 } 749 ); 750 751 die ("search failed with ",$mesg->code(),"\n") if $mesg->code(); 752 753 For directory schema; 754 755 A file or array can be used for output, in the following example 756 only an array will be used. 757 758 my $schema = $ldap->schema(); 759 my @data = (); 760 my $dsml = Net::LDAP::DSML->new(output => \@data, pretty_print => 1 ) 761 or die ("DSML object creation problem using an output array.\n"); 762 763 $dsml->write_schema($schema); 764 765 print "Finished printing DSML\n"; 766 767 =head1 DESCRIPTION 768 769 Directory Service Markup Language (DSML) is the XML standard for 770 representing directory service information in XML. 771 772 At the moment this module only writes DSML entry and schema entities. 773 Reading DSML entities is a future project. 774 775 Eventually this module will be a full level 2 consumer and producer 776 enabling you to give you full DSML conformance. Currently this 777 module has the ability to be a level 2 producer. The user must 778 understand the his/her directory server will determine the 779 consumer and producer level they can achieve. 780 781 To determine conformance, it is useful to divide DSML documents into 782 four types: 783 784 1.Documents containing no directory schema nor any references to 785 an external schema. 786 2.Documents containing no directory schema but containing at 787 least one reference to an external schema. 788 3.Documents containing only a directory schema. 789 4.Documents containing both a directory schema and entries. 790 791 A producer of DSML must be able to produce documents of type 1. 792 A producer of DSML may, in addition, be able to produce documents of 793 types 2 thru 4. 794 795 A producer that can produce documents of type 1 is said to be a level 796 1 producer. A producer than can produce documents of all four types is 797 said to be a level 2 producer. 798 799 =head1 CALLBACKS 800 801 The module uses callbacks to improve performance (at least the appearance 802 of improving performance ;) and to reduce the amount of memory required to 803 parse large DSML files. Every time a single entry or schema is processed 804 we pass the Net::LDAP object (either an Entry or Schema object) to the 805 callback routine. 806 807 =head1 CONSTRUCTOR 808 809 =over 4 810 811 =item new () 812 813 Creates a new Net::LDAP::DSML object. There are 2 options 814 to this method. 815 816 C<output> is a reference to either a file handle that has already 817 been opened or to an array. 818 819 C<pretty_print> is an option to print a new line at the end of 820 each element sequence. It makes the reading of the XML output 821 easier for a human. 822 823 B<Example> 824 825 my $dsml = Net::LDAP::DSML->new(); 826 Prints xml data to standard out. 827 828 my $dsml = Net::LDAP::DSML->new(output => \@array); 829 my $dsml = Net::LDAP::DSML->new(output => *FILE); 830 Prints xml data to a file or array. 831 832 my $dsml = Net::LDAP::DSML->new(output => \@array, pretty_print => 1); 833 my $dsml = Net::LDAP::DSML->new(output => *FILE, pretty_print => 1); 834 Prints xml data to a file or array in pretty print style. 835 836 =back 837 838 839 =head1 METHODS 840 841 =over 4 842 843 =item start_dsml () 844 845 Start a DSML file. 846 847 =item end_dsml () 848 849 End a DSML file. 850 851 =item write_entry ( ENTRY ) 852 853 Entry is a Net::LDAP::Entry object. The write method will parse 854 the LDAP data in the Entry object and put it into DSML XML 855 format. 856 857 B<Example> 858 859 my $entry = $mesg->entry(); 860 $dsml->write_entry($entry); 861 862 =item write_schema ( SCHEMA ) 863 864 Schema is a Net::LDAP::Schema object. The write_schema method will 865 parse the LDAP data in the Schema object and put it into DSML XML 866 format. 867 868 B<Example> 869 870 my $schema = $ldap->schema(); 871 $dsml->write_schema($schema); 872 873 =back 874 875 =head1 AUTHOR 876 877 Graham Barr gbarr@pobox.com 878 879 =head1 SEE ALSO 880 881 L<Net::LDAP>, 882 L<XML::SAX::Base> 883 884 =head1 COPYRIGHT 885 886 Copyright (c) 2002-2006 Graham Barr. All rights reserved. This program is 887 free software; you can redistribute it and/or modify it under the same 888 terms as Perl itself. 889 890 =cut 891 892
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |