如何将嵌套字符串(元数据)包装到 TagGroup 中
How to wrap nested string (metadata) into TagGroup
我导入的元数据有一个预定义的嵌套结构(示例如下所示),导入到DM后是一个字符串。
整个元数据和每个分支级别都包含在大括号 {} 中,所有键和键值都包含在引号 "" 中并以冒号分隔:
我的问题是,如何转换数据并将它们包装到 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": ""
}
正如迈克在评论中指出的那样,这是一项繁琐而不是困难的任务。最好在单独的 class 中创建一个小的解析器脚本来转换格式
"NAME: {
到标签 NAME 的 TagGroups 加上增加的层次结构级别。
和
"NAME": "VALUE"
到标签 NAME 和值 VALUE 的 Tags。
和
}
进入 'reduce hierachy level' 步。
请注意,您始终可以在创建标签组时使用字符串,即使您想在稍后的时间点将其作为数字读出。
递归浏览并记住您所在的 "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"
此外,在解析时,请注意制表符和行 return 字符。 (使用 \t 和 \n 搜索它们。在字符串中指定 int 时可能需要使用“\n”和“\t”,因为 \ 将被解释为控制字符。)
编辑:现在修正代码
我确定可以使用更简洁的版本,但它可以完成任务:
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)
}
我导入的元数据有一个预定义的嵌套结构(示例如下所示),导入到DM后是一个字符串。 整个元数据和每个分支级别都包含在大括号 {} 中,所有键和键值都包含在引号 "" 中并以冒号分隔:
我的问题是,如何转换数据并将它们包装到 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": ""
}
正如迈克在评论中指出的那样,这是一项繁琐而不是困难的任务。最好在单独的 class 中创建一个小的解析器脚本来转换格式
"NAME: {
到标签 NAME 的 TagGroups 加上增加的层次结构级别。
和
"NAME": "VALUE"
到标签 NAME 和值 VALUE 的 Tags。
和
}
进入 'reduce hierachy level' 步。
请注意,您始终可以在创建标签组时使用字符串,即使您想在稍后的时间点将其作为数字读出。
递归浏览并记住您所在的 "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"
此外,在解析时,请注意制表符和行 return 字符。 (使用 \t 和 \n 搜索它们。在字符串中指定 int 时可能需要使用“\n”和“\t”,因为 \ 将被解释为控制字符。)
编辑:现在修正代码
我确定可以使用更简洁的版本,但它可以完成任务:
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)
}