Question Jeff Zhang · 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 

Comments

Guillaume Rongier · Jul 13, 2023

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 existsIf (##class(%Dictionary.ClassDefinition).%ExistsId(produtionClassName))
  {
	// Open the productionset productionDefinition = ##class(%Dictionary.ClassDefinition).%OpenId(produtionClassName)
  }
  Else
  {
	// Create the production definitionset productionDefinition = ##Class(%Dictionary.ClassDefinition).%New()
  }
  //Set productionDefinition.Name         = produtionClassName
  Set productionDefinition.Super        = "Ens.Production"Set productionDefinition.ClassVersion = 25//// Check if the XData Definition already existsIf (##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 DefinitionDo productionDefinition.XDatas.Insert(xdataDefinition)
  //#Dim statusCode As%Status = productionDefinition.%Save()
  //If ($System.Status.IsError(statusCode))
  {
  Return statusCode
  }
  // Compile the production classreturn$System.OBJ.Compile(produtionClassName,"k-d")
}
0
Dmitry Maslennikov · Jul 13, 2023

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

0
Jeff Zhang  Jul 13, 2023 to Dmitry Maslennikov

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 }

    }

}

0