@@ -10,6 +10,7 @@ import (
1010
1111 "github.com/mendixlabs/mxcli/mdl/ast"
1212 "github.com/mendixlabs/mxcli/model"
13+ "github.com/mendixlabs/mxcli/sdk/domainmodel"
1314 "github.com/mendixlabs/mxcli/sdk/microflows"
1415)
1516
@@ -184,12 +185,77 @@ func expressionToXPath(expr ast.Expression) string {
184185 return "empty"
185186 }
186187 return expressionToString (expr )
188+ case * ast.QualifiedNameExpr :
189+ return qualifiedNameToXPath (e )
187190 default :
188191 // For all other expression types, the standard serialization is correct
189192 return expressionToString (expr )
190193 }
191194}
192195
196+ // qualifiedNameToXPath converts a QualifiedNameExpr to XPath format.
197+ // For enum value references (3-part: Module.EnumName.Value), XPath requires
198+ // just the value name in quotes: 'Value'. For 2-part names (associations,
199+ // entity references), returns the qualified name as-is.
200+ func qualifiedNameToXPath (e * ast.QualifiedNameExpr ) string {
201+ // 3-part names (Name contains a dot) are enum references: Module.EnumName.Value
202+ if dotIdx := strings .LastIndex (e .QualifiedName .Name , "." ); dotIdx >= 0 {
203+ valueName := e .QualifiedName .Name [dotIdx + 1 :]
204+ return "'" + valueName + "'"
205+ }
206+ return e .QualifiedName .String ()
207+ }
208+
209+ // memberExpressionToString converts an AST Expression to a Mendix expression string,
210+ // resolving enum string literals to qualified enum names when the attribute type is known.
211+ // For example, 'Processing' becomes MyModule.ENUM_Status.Processing when the attribute
212+ // is of type Enumeration(MyModule.ENUM_Status).
213+ func (fb * flowBuilder ) memberExpressionToString (expr ast.Expression , entityQN , attrName string ) string {
214+ // Only transform string literals for enum attributes
215+ if lit , ok := expr .(* ast.LiteralExpr ); ok && lit .Kind == ast .LiteralString {
216+ if enumRef := fb .lookupEnumRef (entityQN , attrName ); enumRef != "" {
217+ // Convert 'Value' to Module.EnumName.Value
218+ return enumRef + "." + fmt .Sprintf ("%v" , lit .Value )
219+ }
220+ }
221+ return fb .exprToString (expr )
222+ }
223+
224+ // lookupEnumRef returns the enumeration qualified name (e.g., "MyModule.ENUM_Status")
225+ // for an attribute if it is an enumeration type. Returns "" if the attribute is not
226+ // an enumeration or if the domain model is not available.
227+ func (fb * flowBuilder ) lookupEnumRef (entityQN , attrName string ) string {
228+ if fb .reader == nil || entityQN == "" || attrName == "" {
229+ return ""
230+ }
231+ parts := strings .SplitN (entityQN , "." , 2 )
232+ if len (parts ) != 2 {
233+ return ""
234+ }
235+ mod , err := fb .reader .GetModuleByName (parts [0 ])
236+ if err != nil || mod == nil {
237+ return ""
238+ }
239+ dm , err := fb .reader .GetDomainModel (mod .ID )
240+ if err != nil || dm == nil {
241+ return ""
242+ }
243+ for _ , entity := range dm .Entities {
244+ if entity .Name == parts [1 ] {
245+ for _ , attr := range entity .Attributes {
246+ if attr .Name == attrName {
247+ if enumType , ok := attr .Type .(* domainmodel.EnumerationAttributeType ); ok {
248+ return enumType .EnumerationRef
249+ }
250+ return ""
251+ }
252+ }
253+ return ""
254+ }
255+ }
256+ return ""
257+ }
258+
193259// xpathPathExprToString serializes an XPathPathExpr to an XPath path string.
194260func xpathPathExprToString (path * ast.XPathPathExpr ) string {
195261 var parts []string
0 commit comments