[Xml-compile] finding the nillable elements of a sequence type

E R pc88mxer at gmail.com
Fri Oct 19 20:29:55 GMT 2012


In a <sequence> type I would like to determine which fields are
nillable, and so I wrote the following code. The main entry point is:

  $array = nillable($wsdl, "sometypename");

where $wsdl is a XML::Compile::WSDL11 object.

It works for my schema, but I'm not sure if it will work for a general
WSDL schema. Also, am I reinventing some wheels here? Any suggestions
for making the code more general or other improvements would be
welcome.

ER

sub attribute_named {
  my ($node, $key) = @_;
  my @a = grep { $_->nodeName eq $key } ($node->attributes);
  @a ? $a[0]->value : undef;
}

sub find_complex_type {
  my ($wsdl, $typename) = @_;
  $wsdl->namespaces->find(complexType => $typename);
}

sub nillable {
  my ($wsdl, $typename) = @_;
  my $type = find_complex_type($wsdl, $typename);
  unless ($type) { die "no complexType: $typename" }
  my $list = [];
  my $func = sub {
    my ($node) = @_;
    my @attrs = $node->attributes;
    my @nils = grep { $_->nodeName eq "nillable" && $_->value eq
"true" } @attrs;
    my @name = grep { $_->nodeName eq "name" } @attrs;
    if (@nils && @name) { push(@$list, $name[0]->value) }
  };
  each_element($wsdl, $type->{node}, $func);
  return $list;
}

sub each_element {
  my ($wsdl, $node, $func) = @_;

  my $n = $node->nodeName;

  if ($n eq "complexType" || $n eq "sequence" || $n eq "complexContent") {
    for my $child ($node->childNodes) { each_element($wsdl, $child, $func) }
  } elsif ($n eq "element") {
    $func->($node);
  } elsif ($n eq "extension") {
    my $base = attribute_named($node, "base");
    return unless $base;  # emit warning?

    my $translator = XML::Compile::Translate->new('READER', nss =>
$wsdl->namespaces);
    my $typename = $translator->rel2abs('', $node, $base);
    my $type  = find_complex_type($wsdl, $typename);
    if ($type) {
      each_element($wsdl, $type->{node}, $func);
    } # else emit warning?
    for my $child ($node->childNodes) { each_element($wsdl, $child, $func) }
  }
}



More information about the Xml-compile mailing list