A Question about how to programmatically modify XData Block
I have a question about how to modify a XData Block programmatically . Assume i have a impl.cls and there is a XData Block (like XData OpenAPI [ MimeType = application/json ]) in the impl.cls. In other class, can i write a fucntion to modify the context in the XData Block?
Ps: The document already show how to read the XData blcok, if i want to insert something into the block and save it back, how can i do this programmatically (eg write a method and read the block from other class, write something into the block and save it ) ??
Thanks
Here is an example code to modify or create a production XData block, i guess you can adapt to you needs :
ClassMethod CreateProduction( package As %String = "test", name As %String = "AutoCreatedProduction", xdata As %CharacterStream) As %Status { #Dim produtionClassName As %String = package _ "." _ name If ('$ZName(produtionClassName, 4)) { Return $System.Status.Error(5001, "Invalid Production package or name.") } #Dim productionDefinition As %Dictionary.ClassDefinition // Check if the production already exists If (##class(%Dictionary.ClassDefinition).%ExistsId(produtionClassName)) { // Open the production set productionDefinition = ##class(%Dictionary.ClassDefinition).%OpenId(produtionClassName) } Else { // Create the production definition set productionDefinition = ##Class(%Dictionary.ClassDefinition).%New() } // Set productionDefinition.Name = produtionClassName Set productionDefinition.Super = "Ens.Production" Set productionDefinition.ClassVersion = 25 // // Check if the XData Definition already exists If (##Class(%Dictionary.XDataDefinition).%ExistsId(produtionClassName_"||ProductionDefinition")) { // delete the XData Definition $$$ThrowOnError(##Class(%Dictionary.XDataDefinition).%DeleteId(produtionClassName_"||ProductionDefinition")) } #Dim xdataDefinition As %Dictionary.XDataDefinition = ##Class(%Dictionary.XDataDefinition).%New() // Set xdataDefinition.Name = "ProductionDefinition" // Do xdataDefinition.Data.CopyFrom(xdata) // // Insert XData Definition into Production Definition Do productionDefinition.XDatas.Insert(xdataDefinition) // #Dim statusCode As %Status = productionDefinition.%Save() // If ($System.Status.IsError(statusCode)) { Return statusCode } // Compile the production class return $System.OBJ.Compile(produtionClassName,"k-d") }
Not so much magic in it, if you already know how to read it, the content of XData is just a Stream, which can be used both ways. Just Write to it, and %Save it. And you will probably need to compile the class
Class Demo.Test { XData OpenAPI [ MimeType = application/json ] { } ClassMethod Update() { set xdata = ##class(%Dictionary.XDataDefinition).IDKEYOpen($ClassName(), "OpenAPI") do xdata.Data.Write("{}") do xdata.%Save() } }
In VSCode, the content of XData will not appear after that, because it happened on the server, and VSCode will not see the changes, you'll need to export it manually
Thank yo very much for your reply. a quick follow up question, since i am trying to modify some JSON context in the XData Block, how do i do if i want to write something in a specific location ?
Suppose the XData block like this and i want to change the "info" 's value to {"name" : "Alex "}
Xdata {
{
"info" : { "name" : Jeff }
}
}