Question
· Jan 19, 2020

Mass XSD export

I have a large amount of classes in several XML namespaces.

Is there a way to generate all XSDs automatically?

I've read the docs but it seems like it's a manual class-by-class process.

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

Here's what I came up with:

Query ClassListAll() As %SQLQuery
{
SELECT Name
FROM %Dictionary.ClassDefinition
}

Query ClassListNS(namespace) As %SQLQuery
{
SELECT Name
FROM %Dictionary.ClassDefinitionQuery_SubclassOf('%XML.Adaptor') c
WHERE 1=1
    AND EXISTS (SELECT 1
                FROM %Dictionary.ParameterDefinition
                WHERE parent = c.Name
                AND Name = 'NAMESPACE'
                AND _Default = :namespace)
}

/// Should be rewritten to return only non-empty namespaces
Query NSList() As %SQLQuery
{
SELECT DISTINCT _Default Name
FROM %Dictionary.ParameterDefinition
WHERE 1=1
    AND Name = 'NAMESPACE'
}

/// do ##class().ExportAllSchemas()
ClassMethod ExportAllSchemas()
{
    set rs = ..NSListFunc()
    while rs.%Next() {
        write "Exporting: ", rs.Name,!
        do ..ExportSchema(rs.Name)
    }
}

/// do ##class().ExportSchema()
ClassMethod ExportSchema(namespace)
{
    kill %objlasterror
    set schema=##class(%XML.Schema).%New()
    set schema.DefaultNamespace=namespace

    
    #dim empty As %Boolean = $$$YES
    #dim rs As %SQL.ISelectResult
    set rs = ..ClassListNSFunc(namespace)
    while rs.%Next() {
        set empty = $$$NO
        set sc = schema.AddSchemaType(rs.Name)
        write:$$$ISERR(sc) $System.Status.GetErrorText(sc)
    }
    if empty {
        write "Empty namespace",!
        quit
    }
    
    do ..AddImports(namespace, schema)
    
    set schema=schema.GetSchema(namespace)

    #dim writer As %XML.Writer = ##class(%XML.Writer).%New()
    set writer.NoXMLDeclaration = $$$YES
    set writer.Indent = $$$YES
    set writer.SuppressXmlns = $$$YES
    do writer.AddSchemaNamespace("s")
    do writer.OutputToFile(..NsToFullFileName(namespace))

    do writer.AddSchemaNamespace()
    do writer.AddNamespace(namespace)

    set sc = writer.DocumentNode(schema)
    write:$$$ISERR(sc) $System.Status.GetErrorText(sc)
}

ClassMethod AddImports(namespace, schema As %XML.Schema)
{
    set rs = ..NSListFunc()
    while rs.%Next() {
        set curNS = rs.Name
        continue:curNS=namespace
        do schema.DefineLocation(curNS, ..NsToLocalFileName(curNS))
    }
}

ClassMethod NsToFullFileName(namespace) As %String [ CodeMode = expression ]
{
##class(%File).SubDirectoryName($system.Util.ManagerDirectory(), "Temp", 1) _ ..NsToLocalFileName(namespace)
}

ClassMethod NsToLocalFileName(namespace) As %String [ CodeMode = expression ]
{
..NsToFileName(namespace) _ ".xsd"
}

ClassMethod NsToFileName(namespace) As %String [ CodeMode = expression ]
{
$p(namespace, "/", *-1)
}