Skip to content

Instantly share code, notes, and snippets.

@SysProfile
Last active May 28, 2025 17:19
Show Gist options
  • Save SysProfile/8c18a8b3717abde3a5fa81af67174244 to your computer and use it in GitHub Desktop.
Save SysProfile/8c18a8b3717abde3a5fa81af67174244 to your computer and use it in GitHub Desktop.
jSON2XML Pharser
' Ejemplo de uso:
API.Function("SetDynamicValue1", Value:="datos")
API.Function("SetDynamicValue2", Value:="{""persona"":{""nombre"":""Juan"",""edad"":30}}")
API.Function("ScriptStart", Value:="jSON2XML")
Luego, para leer el resultado:
Dim xml As String = API.XML()
Dim doc As New Xml.XmlDocument()
doc.LoadXml(xml)
Dim nodo As Xml.XmlNode = doc.SelectSingleNode("//dynamic/value[@key='DynamicValue2']")
Dim valor As String = If(nodo IsNot Nothing, nodo.InnerText, "No encontrado")
' JSON to XML Converter for vMix (jSON2XML) - Versión Optimizada Sin Librerías Externas
' Script que convierte JSON a XML usando parsing manual estructurado
' Archivo: Scripts/jSON2XML.vb
'
' Usage:
' 1. Set root element name: API.Function("SetDynamicValue1", Value:="rootName")
' 2. Set JSON string/path: API.Function("SetDynamicValue2", Value:="jsonString or filePath")
' 3. Start conversion: API.Function("ScriptStart", Value:="jSON2XML")
' 4. Get result from DynamicValue2
' Obtener parámetros desde los valores dinámicos
Dim rootName As String = ""
Dim inputValue As String = ""
Try
Dim xml As String = API.XML()
Dim doc As New Xml.XmlDocument()
doc.LoadXml(xml)
Dim nodoRootName As Xml.XmlNode = doc.SelectSingleNode("//dynamic/value[@key='DynamicValue1']")
If nodoRootName IsNot Nothing Then rootName = nodoRootName.InnerText
Dim nodoInputValue As Xml.XmlNode = doc.SelectSingleNode("//dynamic/value[@key='DynamicValue2']")
If nodoInputValue IsNot Nothing Then inputValue = nodoInputValue.InnerText
Catch ex As Exception
Console.WriteLine("Error al obtener parámetros: " & ex.Message)
API.Function("SetDynamicValue2", Value:="Error: " & ex.Message)
Exit Sub
End Try
' Usar valor por defecto si no se proporciona nombre raíz
If String.IsNullOrEmpty(rootName) Then rootName = "data"
' Salir si no hay entrada
If String.IsNullOrEmpty(inputValue) Then
API.Function("SetDynamicValue2", Value:="Error: No se proporcionó ningún JSON")
Exit Sub
End If
' Determinar si es archivo o cadena JSON
Dim jsonString As String = ""
Dim isFile As Boolean = False
Dim outputFilePath As String = ""
Try
If IO.File.Exists(inputValue) Then
jsonString = IO.File.ReadAllText(inputValue, System.Text.Encoding.UTF8)
isFile = True
outputFilePath = IO.Path.ChangeExtension(inputValue, "xml")
Else
jsonString = inputValue
End If
Catch ex As Exception
API.Function("SetDynamicValue2", Value:="Error al leer archivo: " & ex.Message)
Exit Sub
End Try
' Variable global para el índice de procesamiento
Dim globalIndex As Integer = 0
Try
' Limpiar y preparar JSON
jsonString = jsonString.Trim()
globalIndex = 0
' Construir XML resultado
Dim xmlDeclaration As String = "<?xml version=""1.0"" encoding=""UTF-8""?>"
Dim resultado As String = xmlDeclaration & vbCrLf & "<" & ValidarNombreElemento(rootName) & ">"
' Procesar JSON principal
resultado &= ProcesarValorJson(jsonString, "")
' Cerrar etiqueta raíz
resultado &= "</" & ValidarNombreElemento(rootName) & ">"
' Formatear resultado
resultado = FormatearXmlBasico(resultado)
' Devolver resultado
If isFile Then
Try
IO.File.WriteAllText(outputFilePath, resultado, System.Text.Encoding.UTF8)
API.Function("SetDynamicValue2", Value:=outputFilePath)
Catch ex As Exception
API.Function("SetDynamicValue2", Value:=resultado)
End Try
Else
API.Function("SetDynamicValue2", Value:=resultado)
End If
Catch ex As Exception
API.Function("SetDynamicValue2", Value:="Error en conversión: " & ex.Message)
End Try
' Función principal para procesar cualquier valor JSON
Function ProcesarValorJson(json As String, elementoPadre As String) As String
SaltarEspacios(json)
If globalIndex >= json.Length Then Return ""
Select Case json(globalIndex)
Case "{"c
Return ProcesarObjeto(json, elementoPadre)
Case "["c
Return ProcesarArray(json, elementoPadre)
Case """"c
Return EscaparXml(LeerCadena(json))
Case Else
Return LeerValorPrimitivo(json)
End Select
End Function
' Función para procesar objetos JSON
Function ProcesarObjeto(json As String, elementoPadre As String) As String
Dim resultado As String = ""
If globalIndex < json.Length AndAlso json(globalIndex) = "{"c Then
globalIndex += 1 ' Saltar '{'
While globalIndex < json.Length
SaltarEspacios(json)
' Fin del objeto
If globalIndex < json.Length AndAlso json(globalIndex) = "}"c Then
globalIndex += 1
Exit While
End If
' Coma entre propiedades
If globalIndex < json.Length AndAlso json(globalIndex) = ","c Then
globalIndex += 1
Continue While
End If
' Leer nombre de propiedad
If globalIndex < json.Length AndAlso json(globalIndex) = """"c Then
Dim nombrePropiedad As String = LeerCadena(json)
SaltarEspacios(json)
' Buscar dos puntos
If globalIndex < json.Length AndAlso json(globalIndex) = ":"c Then
globalIndex += 1
SaltarEspacios(json)
' Procesar valor de la propiedad
Dim nombreElemento As String = ValidarNombreElemento(nombrePropiedad)
Dim valorProcesado As String = ProcesarValorJson(json, nombreElemento)
resultado &= "<" & nombreElemento & ">" & valorProcesado & "</" & nombreElemento & ">"
End If
End If
End While
End If
Return resultado
End Function
' Función para procesar arrays JSON
Function ProcesarArray(json As String, elementoPadre As String) As String
Dim resultado As String = ""
Dim indiceItem As Integer = 0
If globalIndex < json.Length AndAlso json(globalIndex) = "["c Then
globalIndex += 1 ' Saltar '['
While globalIndex < json.Length
SaltarEspacios(json)
' Fin del array
If globalIndex < json.Length AndAlso json(globalIndex) = "]"c Then
globalIndex += 1
Exit While
End If
' Coma entre elementos
If globalIndex < json.Length AndAlso json(globalIndex) = ","c Then
globalIndex += 1
Continue While
End If
' Procesar elemento del array
Dim nombreElemento As String = If(String.IsNullOrEmpty(elementoPadre), "item", elementoPadre) & "_" & indiceItem.ToString()
Dim valorProcesado As String = ProcesarValorJson(json, nombreElemento)
resultado &= "<" & nombreElemento & ">" & valorProcesado & "</" & nombreElemento & ">"
indiceItem += 1
End While
End If
Return resultado
End Function
' Función para leer cadenas JSON
Function LeerCadena(json As String) As String
Dim resultado As String = ""
If globalIndex < json.Length AndAlso json(globalIndex) = """"c Then
globalIndex += 1 ' Saltar primera comilla
While globalIndex < json.Length AndAlso json(globalIndex) <> """"c
If json(globalIndex) = "\"c AndAlso globalIndex + 1 < json.Length Then
' Manejar caracteres escapados básicos
globalIndex += 1
Select Case json(globalIndex)
Case """"c
resultado &= """"
Case "\"c
resultado &= "\"
Case "/"c
resultado &= "/"
Case "b"c
resultado &= vbBack
Case "f"c
resultado &= vbFormFeed
Case "n"c
resultado &= vbLf
Case "r"c
resultado &= vbCr
Case "t"c
resultado &= vbTab
Case Else
resultado &= json(globalIndex)
End Select
Else
resultado &= json(globalIndex)
End If
globalIndex += 1
End While
If globalIndex < json.Length Then globalIndex += 1 ' Saltar última comilla
End If
Return resultado
End Function
' Función para leer valores primitivos (números, booleanos, null)
Function LeerValorPrimitivo(json As String) As String
Dim resultado As String = ""
While globalIndex < json.Length AndAlso Not (json(globalIndex) = ","c OrElse json(globalIndex) = "}"c OrElse json(globalIndex) = "]"c OrElse Char.IsWhiteSpace(json(globalIndex)))
resultado &= json(globalIndex)
globalIndex += 1
End While
Return resultado.Trim()
End Function
' Función para saltar espacios en blanco
Sub SaltarEspacios(json As String)
While globalIndex < json.Length AndAlso Char.IsWhiteSpace(json(globalIndex))
globalIndex += 1
End While
End Sub
' Función para validar nombres de elementos XML
Function ValidarNombreElemento(nombre As String) As String
If String.IsNullOrEmpty(nombre) Then Return "elemento"
Dim resultado As String = ""
' Reemplazar caracteres problemáticos
For Each caracter As Char In nombre
If Char.IsLetterOrDigit(caracter) OrElse caracter = "_"c OrElse caracter = "-"c Then
resultado &= caracter
Else
resultado &= "_"
End If
Next
' Asegurar que comience con letra o guión bajo
If resultado.Length > 0 AndAlso Not Char.IsLetter(resultado(0)) AndAlso resultado(0) <> "_"c Then
resultado = "_" & resultado
End If
If String.IsNullOrEmpty(resultado) Then resultado = "elemento"
Return resultado
End Function
' Función para escapar caracteres especiales XML
Function EscaparXml(texto As String) As String
If String.IsNullOrEmpty(texto) Then Return ""
Return texto.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("""", "&quot;").Replace("'", "&apos;")
End Function
' Función básica para formatear XML con indentación simple
Function FormatearXmlBasico(xmlString As String) As String
Try
Dim doc As New Xml.XmlDocument()
doc.LoadXml(xmlString)
Dim sb As New System.Text.StringBuilder()
Dim configuracion As New Xml.XmlWriterSettings()
configuracion.Indent = True
configuracion.IndentChars = " "
configuracion.NewLineChars = vbCrLf
configuracion.OmitXmlDeclaration = False
configuracion.Encoding = System.Text.Encoding.UTF8
Using writer As Xml.XmlWriter = Xml.XmlWriter.Create(sb, configuracion)
doc.Save(writer)
End Using
Return sb.ToString()
Catch ex As Exception
Return xmlString ' Devolver original si hay error
End Try
End Function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment