Subject: | Namespaces broken for xs:union memberTypes |
The following schema snippet generates broken code:
<xs:simpleType name="DateOrDateTimeType">
<xs:annotation>
<xs:documentation xml:lang="en">A construct to validate either a
date or a dateTime value.</xs:documentation>
</xs:annotation>
<xs:union memberTypes="xs:date xs:dateTime"/>
</xs:simpleType>
The memberTypes of the xs:union need to be normalized. Patch attached.
The patch was written to minimize the changes to existing code. An
alternate solution would factor out code common to both _fixNameSpaces
and _fixMemberTypesNameSpace.
Subject: | union.patch |
--- XML/Pastor/Schema/Parser-1.0.3.pm 2009-04-02 14:32:39.000000000 -0400
+++ XML/Pastor/Schema/Parser.pm 2009-04-02 14:42:09.000000000 -0400
@@ -607,6 +609,8 @@
# attributes of this node.
my $obj = XML::Pastor::Schema::Union->new()->setFields(getAttributeHash($node));
+ $self->_fixMemberTypesNameSpace($obj, $node);
+
if (my $host=$context->findNode(class=>["XML::Pastor::Schema::SimpleType"])) {
$host->base("Union|http://www.w3.org/2001/XMLSchema");
$host->derivedBy("union");
@@ -1046,7 +1050,7 @@
my $opts = {@_};
my $localize= $opts->{localize} || 0;
my $context = $self->context();
- my $verbose = 0;
+ my $verbose = 0; #$self->verbose || 0;
foreach my $field (@$fields) {
my $uri = undef;
@@ -1078,6 +1082,37 @@
return $obj;
}
+sub _fixMemberTypesNameSpace {
+ my $self = shift;
+ my $obj = shift;
+ my $node = shift;
+ my $opts = {@_};
+ my $localize= $opts->{localize} || 0;
+ my $context = $self->context();
+ my $verbose = $self->verbose || 0;
+
+ my @mbts = split ' ', $obj->memberTypes;
+ print STDERR "Fixing up namespaces for 'memberTypes' ('@mbts')...\n" if ($verbose >=9);
+ foreach my $mbt (@mbts) {
+ if ($mbt && ($mbt =~ /\|/)) {
+ # Do nothing. There is already a namespace in there.
+ }elsif ($mbt && ($mbt =~ /:/o)) {
+ # There is a namesapce prefix in there.
+ my ($prefix, $local) = split /:/, $mbt, 2;
+ my $uri = $node->lookupNamespaceURI($prefix);
+ if ($uri) {
+ $mbt = "$local|$uri";
+ }
+ }elsif ($mbt) {
+ if (my $uri = $context->targetNamespace()) {
+ $mbt = "$mbt|$uri";
+ }
+ }
+ }
+ $obj->memberTypes(join ' ', @mbts);
+ return $obj;
+}
+
1;