Question
· Jul 12, 2023

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 

Discussion (3)1
Log in or sign up to continue

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 }

    }

}