1515from .schema import HistoryState
1616from .schema import IfAction
1717from .schema import IfBranch
18+ from .schema import InvokeDefinition
1819from .schema import LogAction
1920from .schema import Param
2021from .schema import RaiseAction
@@ -192,6 +193,11 @@ def parse_state( # noqa: C901
192193 child_history_state = parse_history (child_state_elem )
193194 state .history [child_history_state .id ] = child_history_state
194195
196+ # Parse invoke elements
197+ for invoke_elem in state_elem .findall ("invoke" ):
198+ invoke_def = parse_invoke (invoke_elem )
199+ state .invocations .append (invoke_def )
200+
195201 # Parse donedata (only valid on final states)
196202 if is_final :
197203 donedata_elem = state_elem .find ("donedata" )
@@ -218,6 +224,53 @@ def parse_donedata(element: ET.Element) -> DoneData:
218224 return DoneData (params = params , content_expr = content_expr )
219225
220226
227+ def parse_invoke (element : ET .Element ) -> InvokeDefinition :
228+ """Parse an <invoke> element into an InvokeDefinition."""
229+ type_attr = element .attrib .get ("type" )
230+ typeexpr = element .attrib .get ("typeexpr" )
231+ src = element .attrib .get ("src" )
232+ srcexpr = element .attrib .get ("srcexpr" )
233+ id_attr = element .attrib .get ("id" )
234+ idlocation = element .attrib .get ("idlocation" )
235+ autoforward = element .attrib .get ("autoforward" , "false" ).lower () == "true"
236+ namelist = element .attrib .get ("namelist" )
237+
238+ params = []
239+ content = None
240+ finalize = None
241+ for child in element :
242+ if child .tag == "param" :
243+ name = child .attrib ["name" ]
244+ expr = child .attrib .get ("expr" )
245+ location = child .attrib .get ("location" )
246+ params .append (Param (name = name , expr = expr , location = location ))
247+ elif child .tag == "content" :
248+ # Inline SCXML content: serialize the child <scxml> element back to string
249+ scxml_child = child .find ("{http://www.w3.org/2005/07/scxml}scxml" )
250+ if scxml_child is None :
251+ scxml_child = child .find ("scxml" )
252+ if scxml_child is not None :
253+ content = ET .tostring (scxml_child , encoding = "unicode" )
254+ elif child .text :
255+ content = re .sub (r"\s+" , " " , child .text ).strip ()
256+ elif child .tag == "finalize" :
257+ finalize = parse_executable_content (child )
258+
259+ return InvokeDefinition (
260+ type = type_attr ,
261+ typeexpr = typeexpr ,
262+ src = src ,
263+ srcexpr = srcexpr ,
264+ id = id_attr ,
265+ idlocation = idlocation ,
266+ autoforward = autoforward ,
267+ namelist = namelist ,
268+ params = params ,
269+ content = content ,
270+ finalize = finalize ,
271+ )
272+
273+
221274def parse_transition (trans_elem : ET .Element , initial : bool = False ) -> Transition :
222275 target = trans_elem .get ("target" )
223276
0 commit comments