XML(_XMLName, _Action="", _DB="", _XMLPlural="") { local Result, XMLPath, XMLFile, XMLName static XML_Loaded = "" Format := 1 If Not _DB _DB := %_XMLObject%sDb If Not _Action _Action := "status" XMLFile := _XMLObject . "XML" StringLower, XMLObject, %_XMLName% If Not _XMLPlural _XMLPlural := XMLObject . "s" StringLower, LowerPlural, %_XMLPlural% XMLPath := "/" . LowerPlural If (_Action = "loaded" or _Action = "status") { Result := SA_Get(XML_Loaded, _XMLName) } Else If (_Action = "load") { If Not SA_Get(XML_Loaded, _XMLName) { Result := xpath_load(%XMLFile%, _DB) If Not xpath(%XMLFile%, XMLPath) { xpath(%XMLFile%, XMLPath . "[+1]/@created/text()", A_Now) xpath(%XMLFile%, XMLPath . "/@format/text()", Format) } SA_Set(XML_Loaded, true, _XMLName) } Else Result := true } Else If (_Action = "save") { Result := SA_Get(XML_Loaded, _XMLName) ? xpath_save(%XMLFile%, _DB) : "" } Else if (_Action = "unload") { SA_Set(XML_Loaded, false, _XMLName) Result := true } Else Result := false Return Result } XML_Get(_XMLName, _ID="", _Data="", _XMLPlural="") { local Result, Single, NewVal, XMLFile, XMLObject, XMLPath XMLFile := _XMLObject . "XML" StringLower, XMLObject, %_XMLName% If Not _XMLPlural _XMLPlural := XMLObject . "s" StringLower, LowerPlural, %_XMLPlural% XMLPath := "/" . LowerPlural . "/" . _XMLObject XML(_XMLName, "load") Single := _ID ? true : false Loop { If Single _ID := xpath(%XMLFile%, XMLPath . "[" . A_Index . "]/@id/text()") If Not _ID Break __data := _Data ? xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]/" . _Data . "/text()") : _ID If Single Result := __data Else { If _Data { NewVal := "" NewVal := SA_Set(NewVal, _ID, "id") NewVal := SA_Set(NewVal, __data, "data") Result := SA_Set(Result, NewVal) } Else { Result := SA_Set(Result, __data) } } If Single Break } Return Result } XML_Set(_XMLName, _ID, _Data="", _Value="", _XMLPlural="") { local Result, Param, XMLFile, XMLObject, XMLPath XMLFile := _XMLObject . "XML" StringLower, XMLObject, %_XMLName% If Not _XMLPlural _XMLPlural := XMLObject . "s" StringLower, LowerPlural, %_XMLPlural% XMLPath := "/" . LowerPlural . "/" . _XMLObject XML(_XMLName, "load") If Not xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]") Result := xpath(%XMLFile%, XMLPath . "[+1]/@id[+1]/text()", _ID) If _Data { If (SubStr(_Data, 1, 1) != "@") { If (SubStr(_Data, InStr(_Data, "/", false, 0)+1, 1) = "@") { Param := SubStr(_Data, InStr(_Data, "/", false, 0)+1) _Data := SubStr(_Data, 1, InStr(_Data, "/", false, 0)-1) } If Not xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]/" . _Data) Result := xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]/" . _Data . "[+1]/text()", "") If Param _Data .= "/" . Param } } If _Value Result := xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]/" . _Data . "/text()", _Value) Return Result } XML_Delete(_XMLName, _ID, _Data="", _XMLPlural="") { local Result, XMLFile, XMLObject, XMLPath XMLFile := _XMLObject . "XML" StringLower, XMLObject, %_XMLName% If Not _XMLPlural _XMLPlural := XMLObject . "s" StringLower, LowerPlural, %_XMLPlural% XMLPath := "/" . LowerPlural . "/" . _XMLObject XML(_XMLName, "load") If _Data Result := xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]/" . _Data . "/remove()") Else Result := xpath(%XMLFile%, XMLPath . "[@id=" . _ID . "]/remove()") Return Result } XML_Find(_XMLName, _Subpath = "", _Value = "", _Expr = "", _Return = "", _Set = "", _XMLPlural="") { local Result, Expression, Array, XMLFile, XMLObject, XMLPath XMLFile := _XMLObject . "XML" StringLower, XMLObject, %_XMLName% If Not _XMLPlural _XMLPlural := XMLObject . "s" StringLower, LowerPlural, %_XMLPlural% XMLPath := "/" . LowerPlural . "/" . _XMLObject XML(_XMLName, "load") If Not _Return _Return := "@id" If _Subpath or _Value { If Not _Expr _Expr := "=" Expression := "[" . _Subpath . _Expr . _Value . "]" } Else Expression := "" If _Set Result := xpath(%XMLFile%, XMLPath . Expression . "/" . _Return . "/text()", _Set) Else Result := xpath(%XMLFile%, XMLPath . Expression . "/" . _Return . "/text()") Loop, Parse, Result, `, Array := SA_Set(Array, A_LoopField) Result := Array Return Result }