09-30-2010 02:04 PM
Dear all,
while parsing a xml file with the DOM parser some values in the attributes are read as string variables although they contain only numbers plus decimal point.
I've learned from the help file that "File.Formatter.ParseString" should do the job to convert thge string into a numeric value, but I stumbled to get it working.
How do I initialize the File.Formatter.ParseString method, with which object?
Regards,
Rainer
10-01-2010 01:46 AM
Using this class should work too.
I assume its faster because of the missing interface call.
Just use
dim autoLocale : set autoLocale = new CNumLocale
...
dim val : val = CDbl(textVal)
once at the beginning of your ReadStore function.
Or with the formatter:
dim Formatter : Formatter = File.Formatter
Formatter.DecimalPoint = "."
...
dim dataPointNb : dataPointNb = formatter.ParseString(textVal, eR64)
Please set the formatter to an variable.
File.Formatter.ParseString
is slidely slower than
Formatter.ParseString
because of indirection.
But this tip is for each . in an big loop.
'/**
' @brief Class to set the locale to en-us and set it back when the script finishes
' This is important to make sure that '.' is interpreted as decimal point
'
' @code
' dim autoLocale : set autoLocale = new CNumLocale
' dim val : val = CDbl("1.234")
' autoLocale = NULL
' @endcode
'*/
Class CNumLocale
'/**
' @brief Initialization will set the locale to english to make sure that the
' decimal numbers are interpreted with '.' as decimal point
'*/
Private Sub Class_Initialize
originalLocale_ = GetLocale
SetLocale "en-us"
End Sub
'/**
' @brief Deinitialization of the class. This method is called automatially and
' Will set the locale back to the original value
'*/
Private Sub Class_Terminate
SetLocale originalLocale_
End Sub
private originalLocale_ '///< Old locale setting that will be reestablished after work finished
End Class
10-01-2010 01:59 AM
Another Tip for reading xml from DOM tree and some helper methods.
dim textVal : textVal = XmlValue(parentNode)
is much faster than
dim textVal : textVal = parentNode.textValue
I do not know why. Would asume the internal implementation is the same.
'/**
' @brief Get a child element with the given name
' @param elem The dom element to search a sub child in
' @param name The name of the the sub element. If "" is given as name the first child
' element is picked
' @return a DOMElement object. Use set to assign it to a variable
'*/
Function XmlChild(ByRef elem, ByRef name)
if 1 <> elem.nodeType Then XmlError "This variable is no DOMElement!"
Set XmlChild = Nothing
Dim childElem : For each childElem in elem.childNodes
If 1 = childElem.nodeType then
' Only use DOMElements
if ("" = name) OR (name = childElem.nodeName) then
set XmlChild = childElem
Exit For
End if
End If
Next
End Function
'/**
' @brief Count all child element with the given name
' @param elem The dom element to search sub childs of
' @param name The name of the the sub elements. If "" is given as name all child elements are counted
' @return Number of sub elements with the given name
'*/
Function XmlCountChilds(ByRef elem, ByRef name)
XmlCountChilds = 0
Dim childElem
if "" = name then
For each childElem in elem.childNodes
If 1 = childElem.nodeType then
' Only use DOMElements
XmlCountChilds = XmlCountChilds + 1
End If
Next
else
For each childElem in elem.childNodes
If 1 = childElem.nodeType then
' Only use DOMElements
if name = childElem.nodeName then
XmlCountChilds = XmlCountChilds + 1
End if
End If
Next
end if
End Function
'/**
' @brief Get all child element with the given name
' @param elem The dom element to search sub childs of
' @param name The name of the the sub elements. If "" is given as name all child elements are returned
' @return An array of DOMElements which can be iterated using foreach...
'*/
Function XmlChilds(ByRef elem, ByRef name)
if 1 <> elem.nodeType Then XmlError "This variable is no DOMElement!"
dim numOfChilds : numOfChilds = XmlCountChilds(elem, name)
dim rv : redim rv(numOfChilds - 1)
Dim childElem
dim index
if "" = name then
index = 0
For each childElem in elem.childNodes
If 1 = childElem.nodeType then
' Only use DOMElements
set rv(index) = childElem
index = index + 1
End If
Next
else
index = 0
For each childElem in elem.childNodes
If 1 = childElem.nodeType then
' Only use DOMElements
if name = childElem.nodeName then
set rv(index) = childElem
index = index + 1
End if
End If
Next
end if
XmlChilds = rv
End Function
'/**
' @brief Get the value of a given attribute
' @param elem The DOMElement to look for an attached attribute
' @param name Name of the attribute
' @return A string containing the attribute value. If the attribute was not found an error is raised
' @code
' <elem attrib="1232"/>
' dim value : value = XmlAttribute(elem, "attrib")
' Will return 1232 as CString
' @endcode
'*/
Function XmlAttribute(ByRef elem, ByRef name)
if 1 <> elem.nodeType Then XmlError "This variable is no DOMElement!"
XmlAttribute = NULL
dim attrib : set attrib = elem.Attributes.getNamedItem(name)
if attrib Is Nothing then
XmlError "Attribute """ & name & """ does not exist on this element!"
end if
XmlAttribute = attrib.nodeValue
End Function
'/**
' @brief Get the value of a given attribute if the attribute does not exist "" is returned
' @param elem The DOMElement to look for an attached attribute
' @param name Name of the attribute
' @return A string containing the attribute value. If the attribute was not found an error is raised
' @code
' <elem attrib="1232"/>
' dim value : value = XmlAttribute(elem, "attrib")
' Will return 1232 as CString
' @endcode
'*/
Function XmlAttributeNoRaise(ByRef elem, ByRef name)
if 1 <> elem.nodeType Then XmlError "This variable is no DOMElement!"
dim attrib : set attrib = elem.Attributes.getNamedItem(name)
if attrib Is Nothing then
XmlAttributeNoRaise = ""
Else
XmlAttributeNoRaise = attrib.nodeValue
end if
End Function
'/**
' @brief Get value of the embedded DOMTextElement
' @param elem The DOMElement to look for an embedded text element
' @return A string containing the attribute value. If none text element is embedded "" is returned
' @code
' <elem>abc</elem>
' dim value : value = XmlValue(elem)
' Will return abc as CString
'
' and
'
' <elem/>
' dim value : value = XmlValue(elem)
' Will return "" as CString
' @endcode
'*/
Function XmlValue(ByRef elem)
if 1 <> elem.nodeType Then XmlError "This variable is no DOMElement!"
XmlValue = ""
Dim childElem : For each childElem in elem.childNodes
If 3 = childElem.nodeType then
' Only use DOMText
XmlValue = childElem.nodeValue
End If
Next
End Function
'/**
' @brief Get the name of a DOMElement
' @param elem Element to get the name of
' @return The name of the element. If the given element is not a DOMElement an error is raised
'*/
Function XmlName(ByRef elem)
if 1 <> elem.nodeType Then XmlError "This variable is no DOMElement!"
XmlName = elem.nodeName
End Function
'/**
' @brief Raise an vbs error with the given description
' @param errorDescription Error description to be attached to the raised error
'*/
Sub XmlError(ByRef errorDescription)
Err.Description = errorDescription
Err.Raise 6
End Sub
10-01-2010 07:23 AM
Hi SundanceKid,
The File.Formatter.ParseString function is ONLY available in a DataPlugin. There is no way to inistantiate such a File object in a regular DIAdem VBScript because that function is not resident in DIAdem's VBScript host. Only the DataPlugin VBScript host has this implemented.
If you are in a DataPlugin, then you can provide the datatype to use when parsing the string value in the one parameter this function uses:
IntValue = File.Formatter.ParseString(eI32)
RealValue = File.Formatter.ParseString(eR64)
StringValue = File.Formatter.ParseString(eString)
Set TimeValueObj = File.Formatter.ParseString(eTime)
Note that this function assumes you are dealing with a delimited ASCII file (say values separated by commas or tab characters). It will not succeed in getting the next XML tag value.
Brad Turpin
DIAdem Product Support Engineer
National Instruments