Custom Nodes : Conversion Xml to Json architecture

Hello all
I share a Python script to convert old dyf(s) with Xml architecture to new Json architecture (custom node).
Conversion to launch from Dynamo Revit higher than 2.04.

Note
With Dynamo 2.13+ if your custom nodes are written with IronPython2 engine and the dyf’s format is Xml (old dyf architecture) this will default affect to the CPython3 engine instead of the ipy2 engine.

__author__ = "Cyril POUPIN"
__license__ = "MIT"
__version__ = "0.5"

import clr
import sys
import System
from System.IO import Directory, File
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber )

from System.Collections.Generic import List, Dictionary
from System.Threading import *

clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import MessageBox, MessageBoxButtons, MessageBoxIcon, MessageBoxOptions, MessageBoxDefaultButton

my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')
import os
import time
import traceback
clr.AddReference('System.Xml.Linq') 
import System.Xml.Linq as Xml

clr.AddReference('DynamoCoreWpf') 
clr.AddReference('DynamoCore')
clr.AddReference('DynamoRevitDS')
import Dynamo 
from Dynamo.Applications.ViewModel import *
from Dynamo.Graph.Workspaces import *
from Dynamo.Models import *
from Dynamo.ViewModels import *

def fileIsXmlFile(myfile):
	xdoc = Xml.XDocument()
	try:
		xd1 = xdoc.Load(myfile)
		return True
	except:
		return False

# get current folder
folder = IN[0]
debugMode = IN[1]
# create out_save_folders
out_folder = os.path.join(folder, "Saved_Json")
already_json_folder = os.path.join(folder, "not_Save_(already_Json)")
if not Directory.Exists(out_folder):
	Directory.CreateDirectory(out_folder)
#
if not Directory.Exists(already_json_folder):
	Directory.CreateDirectory(already_json_folder)		
# access to the current Dynamo instance and workspace
dynamoRevit = Dynamo.Applications.DynamoRevit()
dynamoApp = Dynamo.Applications
# Access current version of dynamo
model = dynamoRevit.RevitDynamoModel
#
# get current dynamoViewModel
config = DynamoViewModel.StartConfiguration()
config.DynamoModel = model
dynamoViewModel = DynamoRevitViewModel.Start(config)
#
engine = model.EngineController
version = dynamoRevit.RevitDynamoModel.Version
debug = []
errors = []
i = 0
#
for filename in os.listdir(folder):
    f = os.path.join(folder, filename)
    # checking if it is a file
    if os.path.isfile(f) :
		if filename.endswith('.dyf') and fileIsXmlFile(f):
			i += 1
			pathscript = f 
			out_pathscript = out_folder + "\\" + filename
			pathname, extension = os.path.splitext(out_pathscript)
			# process with DynamoModel
			dynamoRevit.RevitDynamoModel.OpenFileFromPath(pathscript, True)
			currentWorkspace = dynamoRevit.RevitDynamoModel.CurrentWorkspace
			# Save Script
			# try with DynamoViewModel
			try:
				new_model = dynamoRevit.RevitDynamoModel
				config.DynamoModel = new_model
				currentWksIdx = dynamoViewModel.CurrentWorkspaceIndex
				debug.append(currentWksIdx)
				currentSpace = dynamoViewModel.CurrentSpaceViewModel
				debug.append(currentSpace.Name)
				dynamoViewModel.SaveAs(out_pathscript, False)
			# if failed try with WorkSpaceModel
			except Exception as ex:
				try:
					errors.append("Failed Conversion with DynamoViewModel.SaveAs() method.\nTrying with WorkSpaceModel.Save()\nName of Script : {}".format(filename))
					currentWorkspace.Save(out_pathscript, False, None)
				except Exception as ex:
					errors.append([filename, traceback.format_exc()])
			#
			time.sleep(0.1)
			model.RemoveWorkspace(currentWorkspace)
			if debugMode and i == 10:
				break
		else:
			out_pathscript = already_json_folder + "\\" + filename
			File.Copy(f, out_pathscript)
			
dynamoViewModel.Dispose()

MessageBox.Show("Conversion Finished, Close and Quit Dynamo", "Conversion", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)

OUT = errors

Example of conversion from Revit 2021 (Dynamo 2.6)
dyf xml to dyf json3

related topic

Note 1:
as of the day this post is written, I recommend to Revit 2021 for conversion to maintain retro compatibility

Note 2:
any comments for improvement or correction are welcome, in particular how to get the current DynamoViewModel object without going through a Dynamo extension
Update script xml to json_v5.dyn (10.6 KB)

13 Likes

A very nice use of the DynamoCore API !

1 Like