@@ -435,6 +435,12 @@ Sets the default encoding for use in XML declarations.
435435Specify the dtd. The value should be an array reference with three
436436values; the type, the name and the uri.
437437
438+ =head2 xml
439+
440+ This is an hash ref value that should contain the version, encoding and dtd
441+ values (same as above). This is used in case C<conformance > is set to C<loose > ,
442+ but you still want to use the xml declaration or prolog.
443+
438444=head1 IMPORT ARGUMENTS
439445
440446use XML::Generator ':option';
@@ -620,6 +626,10 @@ sub new {
620626 $options {' escape' } = 0;
621627 }
622628
629+ if ($options {' xml' } && ref $options {' xml' } ne ' HASH' ) {
630+ Carp::croak(" XML arguments must be a hash" );
631+ }
632+
623633 if (ref $options {' namespace' } eq ' ARRAY' ) {
624634 if (@{ $options {' namespace' } } > 2 && (@{ $options {' namespace' } } % 2) != 0) {
625635 Carp::croak " odd number of arguments for namespace" ;
@@ -768,23 +778,38 @@ explicitly provide undef as the value.
768778
769779=cut
770780
781+ sub _allow_xml_cmd {
782+ my $this = shift ;
783+ return 1 if $this -> {conformance } eq ' strict' ;
784+ return 1 if defined $this -> {xml };
785+ return 0;
786+ }
787+
788+
771789sub xmldecl {
772- my ( $this , @args ) = @_ ;
790+ my $this = shift ;
773791
774- return $this -> XML::Generator::util::tag(' xmldecl' , @_ )
775- unless $this -> {conformance } eq ' strict' ;
792+ return $this -> XML::Generator::util::tag(' xmldecl' , @_ ) unless $this -> {conformance } eq ' strict' ;
793+ return $this -> _xmldecl(@_ );
794+ }
795+
796+ sub _xmldecl {
797+ my $this = shift ;
798+ my @args = @_ ;
776799
777- my $version = $this -> {' version' } || ' 1.0' ;
800+ return unless $this -> _allow_xml_cmd;
801+
802+ my $version = $this -> {xml }{version } // $this -> {' version' } || ' 1.0' ;
778803
779804 # there's no explicit support for encodings yet, but at the
780805 # least we can know to put it in the declaration
781- my $encoding = $this -> {' encoding' };
806+ my $encoding = $this -> {xml }{ encoding } // $this -> { ' encoding' };
782807
783808 # similarly, although we don't do anything with DTDs yet, we
784809 # recognize a 'dtd' => [ ... ] option to the constructor, and
785810 # use it to create a <!DOCTYPE ...> and to indicate that this
786811 # document can't stand alone.
787- my $doctype = $this -> xmldtd($this -> {dtd });
812+ my $doctype = $this -> xmldtd($this -> {xml }{ dtd } // $this -> { dtd });
788813 my $standalone = $doctype ? " no" : " yes" ;
789814
790815 for (my $i = 0; $i < $#args ; $i += 2) {
@@ -807,12 +832,9 @@ sub xmldecl {
807832 $version ||= ' ' ;
808833 $standalone ||= ' ' ;
809834
810- my $xml = " <?xml$version$encoding$standalone ?>" ;
811- $xml .= " \n $doctype " if $doctype ;
812-
813- $xml = " $xml \n " ;
814-
815- return $xml ;
835+ my @xml = (" <?xml$version$encoding$standalone ?>" );
836+ push (@xml , $doctype ) if $doctype ;
837+ return join (" \n " , @xml , " " );
816838}
817839
818840=head2 xmldtd
@@ -883,7 +905,7 @@ sub xml {
883905 my $this = shift ;
884906
885907 return $this -> XML::Generator::util::tag(' xml' , @_ )
886- unless $this -> { conformance } eq ' strict ' ;
908+ unless $this -> _allow_xml_cmd ;
887909
888910 unless (@_ ) {
889911 Carp::croak " usage: object->xml( (COMMENT | PI)* XML (COMMENT | PI)* )" ;
@@ -903,7 +925,7 @@ sub xml {
903925 }
904926 }
905927
906- return XML::Generator::final-> new([$this -> xmldecl (), @_ ]);
928+ return XML::Generator::final-> new([$this -> _xmldecl (), @_ ]);
907929}
908930
909931=head1 CREATING A SUBCLASS
0 commit comments