如何将嵌套字符串(元数据)包装到TagGroup

时间:2016-09-26 20:48:54

标签: dm-script

我导入的元数据有一个预定义的嵌套结构(以下显示示例),这是导入到DM后的单个字符串。 整个元数据和每个分支级别都包含在括号{}中,所有键和键值都包含在引号中#34;"并被冒号消灭:

我的问题是,如何转换数据并将它们包装到TagGroup对象中,以便更轻松地完成索引,搜索和数据访问操作?

谢谢!

以下是一个例子:

{
    "Acquisition": {
        "AcquisitionStartDatetime": {
            "DateTime": "1473763749"
        },
        "AcquisitionDatetime": {
            "DateTime": "0"
        },
        "BeamType": "",
        "SourceType": "Monochromator"
    },
    "BinaryResult": {
        "AcquisitionUnit": "",
        "CompositionType": "",
        "DetectorIndex": "3",
        "Detector": "HAADF",
        "PixelSize": {
            "width": "5.408370946750477e-010",
            "height": "5.408370946750477e-010"
        },
        "PixelUnitX": "m",
        "PixelUnitY": "m",
        "Offset": {
            "x": "-2.769085924736244e-007",
            "y": "-2.769085924736244e-007"
        },
        "Encoding": ""
    },
    "Sample": "",
    "GasInjectionSystems": ""
}

2 个答案:

答案 0 :(得分:2)

正如迈克在评论中指出的那样,这是一项繁琐而又艰巨的任务。最好在单独的类中创建一个小的解析器脚本来转换格式

"NAME: {到标签NAME的 TagGroups 以及增加的层次级别。

"NAME": "VALUE"到标签NAME的标签并且值为VALUE。

}进入降低等级水平'步骤

请注意,您可以在创建标记组时始终使用String,即使您希望在稍后的时间点将其读取为数字。

递归浏览并记住" taggroup-level"你在,所以每个新标签都添加在该级别。跳过无效的文本部分。

DigitalMicrograph的F1帮助文档有一个关于字符串的部分,其中列出了您最有可能需要的命令:

String StringAppend( String s1, String s2 ) 
Number StringCompare( String s1, String s2 ) 
Boolean StringIsValid( String str ) 
String StringToLower( String str ) 
String StringToUpper( String str ) 
Number len( String str )
String left( String str, Number count )
String mid( String str, Number offset, Number count )
String right( String str, Number count )
Number find( String s1, String s2 )
Number val( String str )

此外,我发现有时使用叔运算符来处理

中的字符串
number isOK = 1
string str =  isOK == 1 ? "true" : "false"

此外,在解析时,请注意制表符和行返回字符。 (使用\ t和\ n来搜索它们。您可能需要使用" \ n"和" \ t"在字符串中指定int时,\将被解释为控件字符。)

答案 1 :(得分:1)

编辑:现在修复了代码

我确信有一个更清理的版本是可能的,但它完成了任务:

Class CMetaStringToTagGroup
{
    // Find next string bracketed by " in input string, starting search
    // at given index. Returns string and end-position of search
    string FindNextKeyName( object self, string input, number & searchPos )
    {
        number totalLength = len( input )
        number start = 0, end = 0
        while( searchPos < totalLength )
        {
            searchpos++
            if ( "\"" == input.mid(searchpos-1,1) )
            {
                if ( !start ) 
                    start = searchpos-1
                else
                    {
                    end = searchpos-1
                    return input.mid(start+1,end-start-1)
                    }
            }
        }
        return ""
    }

    // Returns the next of either "{" ,  "}" or """ after a collon ":"
    string GetNextIndicator( object self, string input, number & searchPos )
    {
        number totalLength = len( input )
        while( searchPos < totalLength )
        {
            searchpos++        
            if ( "{" == input.mid(searchpos-1,1) )
                return "{"
            if ( "}" == input.mid(searchpos-1,1) )
                return "}"
            if ( "\"" == input.mid(searchpos-1,1) )
                return "\""
        }
        return ""
    }

    // In a tag-path string, find location of last colon 
    number findLastColon( object self, string input )
    {
        number totalLength = len( input )
        number lastPos = -1
        number searchPos = 0
        while( searchPos < totalLength )
        {
            searchpos++
            if ( ":" == input.mid(searchpos-1,1) )
                lastPos = searchpos-1
        }
        return lastPos
    }

    // Parse textstring and create taggroup from it
    TagGroup CreateTagFromText( object self, string input )
    {
        TagGroup rootTG = NewTagGroup()
        string currentPath = ""

        number totalLength = len( input )
        number searchPos = 0 
        number searchPos2
        string keyName, indicator
        while( searchPos < totalLength )
        {
            // search for new key or closing bracket, whatever first 
            searchPos2 = searchPos
            indicator = self.GetNextIndicator( input, searchPos2 )
            keyName = self.FindNextKeyName( input, searchPos )
            if ( ( "}" == indicator ) && (searchpos2<searchPos ) )
            {
                // decrease hierachy
                number cutPos = self.findLastColon( currentPath )
                currentPath = left( currentPath, cutPos )
                result("\n DEC ")
                searchPos = searchPos2
            }
            else
            {
                // Either add value or new  sub-tagGroup
                if ( "" == keyname ) break; // No more keys found
                indicator = self.GetNextIndicator( input, searchPos )
                if ( "" == indicator ) break;   // No more indicator found -- should not happen!

                if ( "{" == indicator )
                {
                    // increase hierachy
                    currentPath += ":" + keyname
                    rootTg.TagGroupSetTagAsTagGroup( currentPath, NewTagGroup() )
                    result("\n INC ("+keyname+")")
                }
                else if ( "\"" == indicator )
                {
                    // Add value
                    searchPos--
                    string valStr = self.FindNextKeyName( input, searchPos )
                    rootTg.TagGroupSetTagAsString( currentPath + ":" + keyname, valStr )
                    result("\n   VAL("+keyname+") ")
                }
            }
        }
        return rootTg
    }
}

{
    // Reading input text
    number fileID = OpenFileForReading("C:\\test.txt")
    object fStream = NewStreamFromFileReference(fileID,1)
    string inputStr = fStream.StreamReadAsText(0, fStream.StreamGetSize())

    // Parsing text
    number searchPos = 0
    TagGroup con = alloc(CMetaStringToTagGroup).CreateTagFromText( inputStr )
    con.TagGroupopenBrowserwindow("",0)
}

enter image description here