[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