[Xml-compile] Schemas with mixed elements

Drew Taylor drew at drewtaylor.com
Wed Aug 13 10:30:48 BST 2008


On 12 Aug 2008, at 23:23, Mark Overmeer wrote:

> * Drew Taylor (drew at drewtaylor.com) [080812 08:36]:
>> * Drew Taylor ([1]drew at drewtaylor.com) [080811 17:16]:
>> From my code diving yesterday, it's worth mentioning that the  
>> mixed_elements
>> => STRUCTURED option stops everything for the Writer.
>
> What do you mean with that?  Example?

I was referring to the bit of code below, and talking about the call  
to panic(). In my sample client, if I specified mixed_elements =>  
'STRUCTURED' the panic was triggered. It was probably more a  
misunderstanding on my part about when I can use STRUCTURAL anyway.

> It is much simpler. The ::Translate contains this code:
>
>    my $mixed = $self->isTrue($node->getAttribute('mixed') || 'false');
>    undef $mixed if $self->{mixed_elements} eq 'STRUCTURAL';
>
> Which means: if 'STRUCTURED', then simply ignore the mixed  
> attribute ;-)
> But it may need to be smarter in future versions.  So:  
> makeMixedElement()
> cannot be called in this case.

Interesting. I'm slowly coming to the conclusion that it will be just  
as much work to do things by hand, than deal with these stupid mixed  
elements! Which makes me very sad because I like the backup of schema  
validation and the simplicity of dealing only with data structures. :-(

>> XML::Simple::XMLout() ?   Probably not.
>> Interesting idea. I think XML::LibXML::Simple could be useful on  
>> the server
>> side to generate the request. I might see the effort involved in  
>> writing
>> XML::LibXML::Simple::XMLout()...
>
> I did not write XML::LibXML::Simple::XMLout(), because I think it is a
> bad idea in the first place; you cannot DWIM correct output  
> generation.
> But if you go into the dark areas, then why not use XML::Simple's  
> version?


I was playing with the following this morning:

sub make_element
{
     my ($parser, $data) = @_;

     # there's got to be a better way...
     my $doc = $parser->parse_string(XMLout($data));
     # uses <opt> as the document root element
     foreach my $child ($doc->documentElement->childNodes)
     {
         next unless $child->nodeType == 1;
         return $child;
     }
}

my $parser = XML::LibXML->new();
my $requester =
{
     Requester =>
     {
         Channel => 'Extranet',
         Code    => 'TO-TEST-PV',
         Company =>
         {
             Is => 'TourOperator',
             Code => { Role => "Rebate", Value => 'xxx', Name =>  
'salesContractId' },
         },
         Country => { Code => 'FR' },
     }
};
my $requester_node = make_element($parser, $requester);

# <Control>
# <Requester Channel="Extranet" Code="TO-TEST-PV"> <Company  
Is="TourOperator">
# <Code Role="Rebate" Value="xxx" Name="salesContractId"/> </Company>
# <Country Code="FR"/> </Requester> </Control>
my $transaction_data = { ...,  Control =>  {  '_' =>  
$requester_node }, ... };
my ($answer, $trace) = $client->( $client->( { xftParam =>  
$transaction_data } ) );

It seems to work, but I have to be careful to not pass attribute  
values in the call to make_element() or I get segfaults. This is  
really ugly and error prone to say the least.

A new question: how can I specify a 'xsi:type="foo"' attribute on an  
element? An example is: <Segment xsi:type="SegmentProductType">. I  
tried passing " 'xsi:type' => 'foo' " in the data structure but it was  
ignored.

Drew






More information about the Xml-compile mailing list