diff --git a/wst/trunk/tests/test_suite/files/att_inherited_maxbound.wsdl b/wst/trunk/tests/test_suite/files/att_inherited_maxbound.wsdl
new file mode 100644
index 000000000..9fd544fb6
--- /dev/null
+++ b/wst/trunk/tests/test_suite/files/att_inherited_maxbound.wsdl
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wst/trunk/tests/test_suite/files/att_inherited_maxbound.xsd b/wst/trunk/tests/test_suite/files/att_inherited_maxbound.xsd
new file mode 100644
index 000000000..cd845ed1a
--- /dev/null
+++ b/wst/trunk/tests/test_suite/files/att_inherited_maxbound.xsd
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wst/trunk/tests/test_suite/test_parsers.pas b/wst/trunk/tests/test_suite/test_parsers.pas
index 87907b4a3..25c16f71d 100644
--- a/wst/trunk/tests/test_suite/test_parsers.pas
+++ b/wst/trunk/tests/test_suite/test_parsers.pas
@@ -108,6 +108,7 @@ type
function load_schema_default_elt_att_form_present() : TwstPasTreeContainer;virtual;abstract;
function load_global_attribute() : TwstPasTreeContainer;virtual;abstract;
+ function load_att_inherited_maxbound() : TwstPasTreeContainer;virtual;
published
procedure EmptySchema();
@@ -181,6 +182,7 @@ type
procedure case_sensitive_import();
procedure global_attribute();
+ procedure att_inherited_maxbound();
end;
{ TTest_XsdParser }
@@ -431,6 +433,11 @@ begin
Result.DefaultSearchNameKinds := NAME_KINDS_DEFAULT;
end;
+function TTest_CustomXsdParser.load_att_inherited_maxbound : TwstPasTreeContainer;
+begin
+ Result := ParseDoc('att_inherited_maxbound');
+end;
+
procedure TTest_CustomXsdParser.EmptySchema();
var
tr : TwstPasTreeContainer;
@@ -4083,6 +4090,61 @@ begin
end;
end;
+procedure TTest_CustomXsdParser.att_inherited_maxbound();
+const s_class_name = 'TSampleType';
+var
+ clsType : TPasClassType;
+ tr : TwstPasTreeContainer;
+
+ procedure CheckProperty(
+ const AName,
+ ADeclaredName,
+ ATypeName : string;
+ const AFieldType : TPropertyType;
+ const AIsArray : Boolean
+ );
+ var
+ prp : TPasProperty;
+ t : TPasType;
+ begin
+ prp := FindMember(clsType,AName) as TPasProperty;
+ CheckNotNull(prp);
+ CheckEquals(AName,prp.Name,'Name');
+ CheckEquals(ADeclaredName,tr.GetExternalName(prp),'External Name');
+ CheckNotNull(prp.VarType);
+ t := GetUltimeType(prp.VarType);
+ CheckNotNull(t,'Property''s Ultime Type not found.');
+ if AIsArray then begin
+ CheckEquals(AIsArray,(t is TPasArrayType));
+ CheckNotNull(TPasArrayType(t).ElType,'array element type');
+ CheckEquals(ATypeName,tr.GetExternalName(TPasArrayType(t).ElType),'TypeName');
+ end else begin
+ CheckEquals(ATypeName,tr.GetExternalName(t),'TypeName');
+ end;
+ CheckEquals(PropertyType_Att[AFieldType],tr.IsAttributeProperty(prp));
+ end;
+
+var
+ mdl : TPasModule;
+ elt : TPasElement;
+begin
+ tr := load_att_inherited_maxbound();
+ try
+ mdl := tr.FindModule('urn:wst-test');
+ CheckNotNull(mdl,'urn:wst-test');
+ elt := tr.FindElement(s_class_name);
+ CheckNotNull(elt,s_class_name);
+ CheckIs(elt,TPasClassType);
+ clsType := elt as TPasClassType;
+ CheckProperty('StringElement','StringElement','string',ptField,True);
+ CheckProperty('IntElement','IntElement','int',ptField,True);
+ CheckProperty('StringAtt','StringAtt','string',ptAttribute,False);
+ CheckProperty('IntAtt','IntAtt','int',ptAttribute,False);
+ finally
+ tr.Free();
+ end;
+end;
+
{ TTest_XsdParser }
function TTest_XsdParser.ParseDoc(
diff --git a/wst/trunk/ws_helper/ws_parser_imp.pas b/wst/trunk/ws_helper/ws_parser_imp.pas
index 44c9c564e..2d79120b3 100644
--- a/wst/trunk/ws_helper/ws_parser_imp.pas
+++ b/wst/trunk/ws_helper/ws_parser_imp.pas
@@ -1234,33 +1234,37 @@ var
locProp.StoredAccessorName := 'True';
end;
- if ABoundInfos.Valid then begin
- locMaxOccur := ABoundInfos.MaxOccurs;
- locMaxOccurUnbounded := ABoundInfos.Unboundded;
- end else begin
+ if locIsAttribute then begin
locMaxOccur := 1;
locMaxOccurUnbounded := False;
- end;
- locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_maxOccurs)]),TDOMNodeRttiExposer));
- locPartCursor.Reset();
- if locPartCursor.MoveNext() then begin
- locStrBuffer := (locPartCursor.GetCurrent() as TDOMNodeRttiExposer).NodeValue;
- if AnsiSameText(locStrBuffer,s_unbounded) then begin
- locMaxOccurUnbounded := True;
+ end else begin
+ if ABoundInfos.Valid then begin
+ locMaxOccur := ABoundInfos.MaxOccurs;
+ locMaxOccurUnbounded := ABoundInfos.Unboundded;
end else begin
- if not TryStrToInt(locStrBuffer,locMaxOccur) then
- raise EXsdParserException.CreateFmt(SERR_InvalidMaxOccursValue,[FTypeName,locName]);
- if ( locMinOccur < 0 ) then
- raise EXsdParserException.CreateFmt(SERR_InvalidMaxOccursValue,[FTypeName,locName]);
+ locMaxOccur := 1;
+ locMaxOccurUnbounded := False;
+ end;
+ locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_maxOccurs)]),TDOMNodeRttiExposer));
+ locPartCursor.Reset();
+ if locPartCursor.MoveNext() then begin
+ locStrBuffer := (locPartCursor.GetCurrent() as TDOMNodeRttiExposer).NodeValue;
+ if AnsiSameText(locStrBuffer,s_unbounded) then begin
+ locMaxOccurUnbounded := True;
+ end else begin
+ if not TryStrToInt(locStrBuffer,locMaxOccur) then
+ raise EXsdParserException.CreateFmt(SERR_InvalidMaxOccursValue,[FTypeName,locName]);
+ if ( locMinOccur < 0 ) then
+ raise EXsdParserException.CreateFmt(SERR_InvalidMaxOccursValue,[FTypeName,locName]);
+ end;
end;
end;
- isArrayDef := locMaxOccurUnbounded or ( locMaxOccur > 1 );
+ isArrayDef := not(locIsAttribute) and (locMaxOccurUnbounded or (locMaxOccur > 1));
if isArrayDef then begin
arrayItems.Add(locProp).FIsCollection := IsCollectionArray(AElement);
end;
- if AnsiSameText(s_attribute,ExtractNameFromQName(AElement.NodeName)) then begin
+ if locIsAttribute then
FSymbols.SetPropertyAsAttribute(locProp,True);
- end;
locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_default)]),TDOMNodeRttiExposer));
locPartCursor.Reset();
if locPartCursor.MoveNext() then