diff --git a/wst/trunk/tests/test_suite/files/global_attribute.wsdl b/wst/trunk/tests/test_suite/files/global_attribute.wsdl
new file mode 100644
index 000000000..271bb1463
--- /dev/null
+++ b/wst/trunk/tests/test_suite/files/global_attribute.wsdl
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wst/trunk/tests/test_suite/files/global_attribute.xsd b/wst/trunk/tests/test_suite/files/global_attribute.xsd
new file mode 100644
index 000000000..ebb2212e3
--- /dev/null
+++ b/wst/trunk/tests/test_suite/files/global_attribute.xsd
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wst/trunk/tests/test_suite/test_parsers.pas b/wst/trunk/tests/test_suite/test_parsers.pas
index 911e6f826..751432601 100644
--- a/wst/trunk/tests/test_suite/test_parsers.pas
+++ b/wst/trunk/tests/test_suite/test_parsers.pas
@@ -80,6 +80,8 @@ type
function load_schema_case_sensitive() : TwstPasTreeContainer;virtual;abstract;
function load_schema_case_sensitive2() : TwstPasTreeContainer;virtual;abstract;
function load_schema_case_sensitive_import() : TwstPasTreeContainer;virtual;abstract;
+
+ function load_global_attribute() : TwstPasTreeContainer;virtual;abstract;
published
procedure EmptySchema();
@@ -132,6 +134,8 @@ type
procedure case_sensitive();
procedure case_sensitive2();
procedure case_sensitive_import();
+
+ procedure global_attribute();
end;
{ TTest_XsdParser }
@@ -189,6 +193,8 @@ type
function load_schema_case_sensitive() : TwstPasTreeContainer;override;
function load_schema_case_sensitive2() : TwstPasTreeContainer;override;
function load_schema_case_sensitive_import() : TwstPasTreeContainer;override;
+
+ function load_global_attribute() : TwstPasTreeContainer;override;
end;
{ TTest_WsdlParser }
@@ -246,6 +252,8 @@ type
function load_schema_case_sensitive() : TwstPasTreeContainer;override;
function load_schema_case_sensitive2() : TwstPasTreeContainer;override;
function load_schema_case_sensitive_import() : TwstPasTreeContainer;override;
+
+ function load_global_attribute() : TwstPasTreeContainer;override;
published
procedure no_binding_style();
procedure signature_last();
@@ -2704,6 +2712,52 @@ begin
end;
end;
+procedure TTest_CustomXsdParser.global_attribute();
+const s_class_name = 'TSampleClass';
+var
+ clsType : TPasClassType;
+ tr : TwstPasTreeContainer;
+
+ procedure CheckProperty(
+ const AName,
+ ADeclaredName,
+ ATypeName : string;
+ const AFieldType : TPropertyType
+ );
+ 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.');
+ CheckEquals(ATypeName,tr.GetExternalName(t),'TypeName');
+ CheckEquals(PropertyType_Att[AFieldType],tr.IsAttributeProperty(prp));
+ end;
+
+var
+ mdl : TPasModule;
+ elt : TPasElement;
+begin
+ tr := load_global_attribute();
+ 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('intAtt','intAtt','int',ptAttribute);
+ CheckProperty('strAtt','strAtt','string',ptAttribute);
+ finally
+ tr.Free();
+ end;
+end;
+
{ TTest_XsdParser }
function TTest_XsdParser.ParseDoc(
@@ -2896,6 +2950,11 @@ begin
Result := ParseDoc('case_sensitive3',True);
end;
+function TTest_XsdParser.load_global_attribute() : TwstPasTreeContainer;
+begin
+ Result := ParseDoc('global_attribute');
+end;
+
function TTest_XsdParser.load_class_widechar_property() : TwstPasTreeContainer;
begin
Result := ParseDoc('class_widechar_property');
@@ -3722,6 +3781,11 @@ begin
Result := ParseDoc('case_sensitive3',True);
end;
+function TTest_WsdlParser.load_global_attribute() : TwstPasTreeContainer;
+begin
+ Result := ParseDoc('global_attribute',True);
+end;
+
initialization
RegisterTest('XSD parser',TTest_XsdParser.Suite);
RegisterTest('WSDL parser',TTest_WsdlParser.Suite);
diff --git a/wst/trunk/ws_helper/ws_parser_imp.pas b/wst/trunk/ws_helper/ws_parser_imp.pas
index bc6c93688..be886b04e 100644
--- a/wst/trunk/ws_helper/ws_parser_imp.pas
+++ b/wst/trunk/ws_helper/ws_parser_imp.pas
@@ -1413,28 +1413,59 @@ var
locAttObj : TPasProperty;
locInternalEltName : string;
locHasInternalName : boolean;
+ locIsRefElement : Boolean;
+ locTypeInternalName : string;
+ locTypeAddRef : Boolean;
begin
+ locIsRefElement := False;
+ locTypeAddRef := True;
locAttCursor := CreateAttributesCursor(AElement,cetRttiNode);
locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_name)]),TDOMNodeRttiExposer));
locPartCursor.Reset();
- if not locPartCursor.MoveNext() then
- raise EXsdInvalidDefinitionException.Create(SERR_InvalidAttributeDef_MissingName);
+ if not locPartCursor.MoveNext() then begin
+ locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_ref)]),TDOMNodeRttiExposer));
+ locPartCursor.Reset();
+ if not locPartCursor.MoveNext() then
+ raise EXsdInvalidDefinitionException.Create(SERR_InvalidAttributeDef_MissingName);
+ locIsRefElement := True;
+ end;
locName := (locPartCursor.GetCurrent() as TDOMNodeRttiExposer).NodeValue;
+ if locIsRefElement then
+ locName := ExtractNameFromQName(locName);
if IsStrEmpty(locName) then
raise EXsdInvalidDefinitionException.Create(SERR_InvalidAttributeDef_EmptyName);
- locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_type)]),TDOMNodeRttiExposer));
- locPartCursor.Reset();
- if not locPartCursor.MoveNext() then
- raise EXsdInvalidDefinitionException.Create(SERR_InvalidAttributeDef_MissingType);
- locTypeName := ExtractNameFromQName((locPartCursor.GetCurrent() as TDOMNodeRttiExposer).NodeValue);
+ if locIsRefElement then begin
+ locTypeName := locName;
+ end else begin
+ locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_type)]),TDOMNodeRttiExposer));
+ locPartCursor.Reset();
+ if not locPartCursor.MoveNext() then
+ raise EXsdInvalidDefinitionException.Create(SERR_InvalidAttributeDef_MissingType);
+ locTypeName := ExtractNameFromQName((locPartCursor.GetCurrent() as TDOMNodeRttiExposer).NodeValue);
+ end;
if IsStrEmpty(locTypeName) then
raise EXsdInvalidDefinitionException.Create(SERR_InvalidAttributeDef_EmptyType);
locType := FSymbols.FindElement(locTypeName) as TPasType;
- if not Assigned(locType) then begin
- locType := TPasUnresolvedTypeRef(FSymbols.CreateElement(TPasUnresolvedTypeRef,locTypeName,Self.Module.InterfaceSection,visPublic,'',0));
- Self.Module.InterfaceSection.Declarations.Add(locType);
- Self.Module.InterfaceSection.Types.Add(locType);
+ if Assigned(locType) then begin
+ if locIsRefElement then begin
+ locTypeInternalName := locTypeName;
+ locTypeInternalName := locTypeInternalName + '_Type';
+ locType.Name := locTypeInternalName;
+ FSymbols.RegisterExternalAlias(locType,locTypeName);
+ end;
+ end else begin
+ locTypeInternalName := ExtractIdentifier(locTypeName);
+ if locIsRefElement or AnsiSameText(locTypeInternalName,locInternalEltName) then begin
+ locTypeInternalName := locTypeInternalName + '_Type';
+ end;
+ if IsReservedKeyWord(locTypeInternalName) then begin
+ locTypeInternalName := '_' + locTypeInternalName;
+ end;
+ locType := TPasUnresolvedTypeRef(FSymbols.CreateElement(TPasUnresolvedTypeRef,locTypeInternalName,nil{Self.Module.InterfaceSection},visDefault,'',0));
+ locTypeAddRef := False;
+ if not AnsiSameText(locTypeInternalName,locTypeName) then
+ FSymbols.RegisterExternalAlias(locType,locTypeName);
end;
locPartCursor := CreateCursorOn(locAttCursor.Clone() as IObjectCursor,ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_use)]),TDOMNodeRttiExposer));
@@ -1458,7 +1489,8 @@ var
locAttObj := TPasProperty(FSymbols.CreateElement(TPasProperty,locInternalEltName,locClassDef,visPublished,'',0));
locClassDef.Members.Add(locAttObj);
locAttObj.VarType := locType as TPasType;
- locAttObj.VarType.AddRef();
+ if locTypeAddRef then
+ locType.AddRef();
if locHasInternalName then
FSymbols.RegisterExternalAlias(locAttObj,locName);
FSymbols.SetPropertyAsAttribute(locAttObj,True);
diff --git a/wst/trunk/ws_helper/xsd_parser.pas b/wst/trunk/ws_helper/xsd_parser.pas
index 1a2f643cf..cc8d70e2f 100644
--- a/wst/trunk/ws_helper/xsd_parser.pas
+++ b/wst/trunk/ws_helper/xsd_parser.pas
@@ -644,7 +644,9 @@ var
typNd := FindNamedNode(crsSchemaChild,localTypeName);
if not Assigned(typNd) then
raise EXsdTypeNotFoundException.CreateFmt(SERR_TypeDefinitionNotFound,['1',AName]);
- if AnsiSameText(ExtractNameFromQName(typNd.NodeName),s_element) then begin
+ if AnsiSameText(ExtractNameFromQName(typNd.NodeName),s_element) or
+ AnsiSameText(ExtractNameFromQName(typNd.NodeName),s_attribute)
+ then begin
crs := CreateCursorOn(CreateAttributesCursor(typNd,cetRttiNode),ParseFilter(Format('%s = %s',[s_NODE_NAME,QuotedStr(s_type)]),TDOMNodeRttiExposer));
crs.Reset();
if crs.MoveNext() then begin
@@ -923,10 +925,11 @@ begin
if Assigned(FChildCursor) then begin
crsSchemaChild := FChildCursor.Clone() as IObjectCursor;
typFilterStr := Format(
- '%s or %s or %s',
+ '%s or %s or %s or %s',
[ CreateQualifiedNameFilterStr(s_complexType,FXSShortNames),
CreateQualifiedNameFilterStr(s_simpleType,FXSShortNames),
- CreateQualifiedNameFilterStr(s_element,FXSShortNames)
+ CreateQualifiedNameFilterStr(s_element,FXSShortNames),
+ CreateQualifiedNameFilterStr(s_attribute,FXSShortNames)
]
);
crsSchemaChild := CreateCursorOn(crsSchemaChild,ParseFilter(typFilterStr,TDOMNodeRttiExposer));