[Xml-compile] adding xml:lang attribute

Petar Shangov pshangov at yahoo.com
Sun Mar 1 21:50:52 GMT 2009


I finally got the scoping within the hooks to work properly, so this is not an issue anymore. I still cannot get the type selector to work though, I am forced to use path selectors, which are less fit for just selecting elements.

I think XML::Compile should allow easier handling of elements from the xml namespace, as long as they are specified in the schema. But then I don't know how XML::Schema is implemented and what problems this may entail ...

Regards,

Petar



----- Original Message ----
> From: Petar Shangov <pshangov at yahoo.com>
> To: Mark Overmeer <mark at overmeer.net>
> Cc: xml-compile at lists.scsys.co.uk
> Sent: Saturday, 28 February, 2009 18:19:01
> Subject: Re: [Xml-compile] adding xml:lang attribute
> 
> Hi Mark,
> 
> I still cannot get this to work properly. The value of $lang seems to get lost 
> and is always undef during the 'after' hook. Admittedly, I am not very good with 
> closures and such. Here is what I have tried:
> 
> # version 1
> { 
>     my $lang;
> 
>     sub before_sub
>     {  
>         my ($doc, $values, $path) = @_;
>         my %copy = %$values;
>        $lang = delete $copy{'lang'}; 
>        warn $lang;
>        return \%copy;
>     };
> 
>     sub after_sub
>     {  
>         my ($doc, $node, $path) = @_;
>        $node->setAttribute('xml:lang' => $lang);
>        return $node;
>     };
> 
>     $schema->addHook(
>         path   => qr(tuv),
>         before => \&before_sub,
>         after  => \&after_sub,
>     );    
> }
> 
> 
> 
> # version 2
> { 
>     my $lang;
> 
>     $schema->addHook(
>         path   => qr(tuv),
>         before => sub {  
>            my ($doc, $values, $path) = @_;
>            my %copy = %$values;
>            $lang = delete $copy{'lang'}; 
>            return \%copy;
>         },
>       after  => sub {  
>            my ($doc, $node, $path) = @_;
>            $node->setAttribute('xml:lang' => $lang);
>            return $node;
>         },
>     );    
> }
> 
> In both cases I get the xml:lang attribute where needed but its value is empty. 
> I ended up using the following:
> 
> sub after_sub
> {  
>   my ($doc, $node, $path) = @_;
>   my $lang = $node->getAttribute('lang');
>   $node->removeAttribute('lang');
>   $node->setAttribute('xml:lang' => $lang);
>   return $node;
> };
> 
> $schema->addHook(
>   path   => qr'tuv$',
>   after  => \&after_sub,
> );
> 
> but it is only a temporary solution - it works because the 'tuv' element allows 
> anyAttribute. And I will need xml:lang (and on several occasions xml:space) in 
> serveral schemas I will be using, and with several different elements within 
> each schema.
> 
> Second question: this is probably something I have not done properly, but I 
> can't get the 'type' selector for adding hoods to work properly. Here is some of 
> the options I tried (instead of 'path'):
> 
> type   => 'tuv'
> type   => '{tmx}tuv' # 'tmx' is defined as a prefix
> type   => '{http://www.lisa.org/tmx20}tuv'
> type   => '{http://www.lisa.org/tmx20}tmx/body/tu/tuv'
> 
> and none triggers the hook (using the 'path' selector as specified above works 
> OK).
> 
> Regards,
> 
> Petar
> 
> 
> 
> ----- Original Message ----
> > From: Mark Overmeer 
> > To: Petar Shangov 
> > Cc: xml-compile at lists.scsys.co.uk
> > Sent: Saturday, 28 February, 2009 1:13:15
> > Subject: Re: [Xml-compile] adding xml:lang attribute
> > 
> > * Petar Shangov (pshangov at yahoo.com) [090227 16:18]:
> > > I need to add the xml:lang attribute to an element, but I can't
> > > seem to figure out how to do it.
> > 
> > There are a few spots where schema's are horrible, many to be
> > backwards compatible.  One is, for instance, the use of xsi:type.
> > Other spots are the attributes which start with xml, and the
> > "namespace" namespace.
> > 
> > And did you known that schema defines a clean "language" type (which
> > maps onto an xml:lang)?
> > 
> > The warnings you get are to be expected.  And probably, there should
> > be a clean way to hide a dirty "hook" trick.  This could be something
> > like:   (untested)
> > 
> >      use XML::Compile::Util qw/XMLNS/;
> >      $schema->new(...  , prefixes => [ xml => XMLNS ] );
> > 
> >      { my $lang;
> > 
> >        # avoid complaint about unused value for lang
> >        sub before($$$)
> >        {   my ($doc, $values, $path) = @_;
> >            my %copy = %$values;
> >            $lang = delete $copy{lang};  # or xml_lang?
> >            \%copy;
> >        }
> > 
> >        sub after($$$)
> >        {   my ($doc, $node, $path) = @_;
> >            $node->setAttribute('xml:lang' => $lang);
> >            $node;
> >        }
> > 
> >        $schema->addHook
> >          ( type   => \@types_with_xmllang
> >          , before => \&before
> >          , after  => \&after
> >          );
> >      }
> >      
> > See... it would be nice to have a predefined hook for this.
> > The other route would be to accept and xml:lang attribute everywhere, but
> > that would be extremely expensive.
> > 
> > This trick is described in XML::Compile::Translate::Writer, as a
> > general trick to work around bugs in schema's.
> > -- 
> > Regards,
> > 
> >                MarkOv
> > 
> > ------------------------------------------------------------------------
> >        Mark Overmeer MSc                                MARKOV Solutions
> >      Mark at Overmeer.net                          solutions at overmeer.net
> > http://Mark.Overmeer.net                  http://solutions.overmeer.net
> 
> 
> _______________________________________________
> Xml-compile mailing list
> Xml-compile at lists.scsys.co.uk
> http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/xml-compile




More information about the Xml-compile mailing list