化学品有一个商品名称(这是通常所指的名称)和一个实际的化学品名称。我需要查一个商品名称,找到它的正确的化学名称,然后得到该化学品的性质。例如:
$tradeName = "Voranol"
if $tradeName == "Voranol" then
$productName = "Polyether Polyol"
$flare = "List I"
$bay = "1"
$listPos = 3
EndIf我有一个包含大量产品的.au3文件。它工作得很好,但是做if $tradeName == "Name1" or $tradeName == "Name2" or $tradeName == "Name4" or $tradeName == "Name5"有点乏味。我也需要能够编辑它的程序。我现在用的是:
if $product == "dowanol pmb" or $product == "dowanol pma" or $product == "dipropylene glycol" or $product == "dowanol pnp" or $productCheck2 == "dowanol pmb" or $productCheck2 == "dowanol pma" or $productCheck2 == "dipropylene glycol" or $productCheck2 == "dowanol pnp" then
$result = "DIPROPYLENE GLYCOL"
$bay = 4
$useFlare = 1
$listPos = 2
elseif $product == "glycol blend" then
$result = "GLYCOL"
$bay = 3
$useFlare = 2
$listPos = 1
elseif $product == "isopar e" or $product == "isopar c" or $product == "isopar h" or $productCheck2 == "isopar h" then
$result = "PETROLEUM NAPTHA"
$bay = 5
$useFlare = 0
$listPos = 1
EndIf
; Note: 0 = No Flare, 1 = Normal Flare, 2 = CAS Flare发布于 2016-03-01 06:15:23
数据库选项的另一个替代方法是使用XML文档存储产品(化学)信息。
您可以轻松地使用XPath查询XML以获得产品名称/属性。维护文件也会相当容易。您甚至可以创建一个XML来对其进行验证,以确保您的文件在修改后仍然有效。
在AutoIt中对XML的处理可以通过几种不同的方式完成:
运行像撒克逊这样的东西可能对你所需要的东西来说太过分了。
MSXML不会太糟糕,应该存在多个UDF。
我会投票给Xmlstarlet。(注:我以前从未以这种方式使用过xmlstarlet。我是撒克逊的超级粉丝,而且几乎完全使用它。对于AutoIt,我使用了MSXML和Saxon的组合;Saxon将复杂的数据转换成一个更小、更简单的子集,然后使用MSXML对该子集执行简单的xpath查询。然而,如果我要做这样的事情,我会认真地看一下xmlstarlet。)
另外,如果您的数据增长到一个XML文件没有意义,那么您可以将它分割成一个较小的文件集合;可能是单个产品。您还可能达到这样的程度:将这些文件加载到实际的XML数据库中可能是有意义的(eXistdb是一种选择)。
下面是一个简单的XML示例(模式和实例):
XSD (products.xsd)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="product"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="product">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="tradenames"/>
</xs:sequence>
<xs:attribute name="bay" use="required" type="xs:integer"/>
<xs:attribute name="listpos" use="required" type="xs:integer"/>
<xs:attribute name="useflare" use="required" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element name="tradenames">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="name" type="xs:string"/>
</xs:schema>XML (products.xml)
<products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="products.xsd">
<product bay="4" useflare="1" listpos="2">
<name>DIPROPYLENE GLYCOL</name>
<tradenames>
<name>dowanol pmb</name>
<name>dowanol pma</name>
<name>dipropylene glycol</name>
<name>dowanol pnp</name>
</tradenames>
</product>
<product bay="3" useflare="2" listpos="1">
<name>GLYCOL</name>
<tradenames>
<name>glycol blend</name>
</tradenames>
</product>
<product bay="5" useflare="0" listpos="1">
<name>PETROLEUM NAPTHA</name>
<tradenames>
<name>isopar e</name>
<name>isopar c</name>
<name>isopar h</name>
</tradenames>
</product>
</products>这里有一些AutoIt,它使用MSXML来演示加载XML (针对XSD的验证)并搜索具有包含“乙二醇”的商品名称的产品。
AutoIt
;~ AutoIt Version: 3.3.14.2
;String to search on.
$searchString = "glycol"
ConsoleWrite("Search string: '" & $searchString & "'" & @CRLF)
;XPath for searching trade names. Search string is injected (code injection; escaping of strings would be a very good idea!).
$xpath_tradename = "/products/product[tradenames/name[contains(.,'" & $searchString & "')]]"
ConsoleWrite("XPath: '" & $xpath_tradename & "'" & @CRLF)
$msxml = ObjCreate('MSXML2.DOMDocument.6.0')
If IsObj($msxml) Then
$msxml.async = False
$msxml.validateOnParse = True
$msxml.resolveExternals = True
$msxml.setProperty("SelectionLanguage", "XPath")
$msxml.load('products.xml')
If $msxml.parseError.errorCode = 0 Then
$prods = $msxml.SelectNodes($xpath_tradename)
If IsObj($prods) And $prods.Length > 0 Then
ConsoleWrite("Number of products found: '" & $prods.Length & "'" & @CRLF)
For $prod In $prods
ConsoleWrite(@CRLF & "------ PRODUCT ------" & @CRLF)
ConsoleWrite("Product name: '" & $prod.SelectSingleNode('name').text & "'" & @CRLF)
ConsoleWrite("Product bay: '" & $prod.getAttribute('bay') & "'" & @CRLF)
Next
ConsoleWrite(@CRLF)
Else
ConsoleWrite("PRODUCT NOT FOUND" & @CRLF)
EndIf
Else
MsgBox(17, 'Error', 'Error opening XML file: ' & @CRLF & @CRLF & $msxml.parseError.reason)
SetError($msxml.parseError.errorCode)
EndIf
EndIf控制台输出
Search string: 'glycol'
XPath: '/products/product[tradenames/name[contains(.,'glycol')]]'
Number of products found: '2'
------ PRODUCT ------
Product name: 'DIPROPYLENE GLYCOL'
Product bay: '4'
------ PRODUCT ------
Product name: 'GLYCOL'
Product bay: '3'发布于 2016-02-28 11:52:00
Autoit中最好的数据库解决方案是SQLite。
如果你想像专业人士那样做,你应该使用SQLite。
#include <SQLite.au3>
#include <SQLite.dll.au3>
Local $hQuery, $aRow
_SQLite_Startup()
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & @CRLF)
_SQLite_Open()
; Without $sCallback it's a resultless statement
_SQLite_Exec(-1, "Create table tblTest (a,b int,c single not null);" & _
"Insert into tblTest values ('1',2,3);" & _
"Insert into tblTest values (Null,5,6);")
Local $d = _SQLite_Exec(-1, "Select rowid,* From tblTest", "_cb") ; _cb will be called for each row
Func _cb($aRow)
For $s In $aRow
ConsoleWrite($s & @TAB)
Next
ConsoleWrite(@CRLF)
; Return $SQLITE_ABORT ; Would Abort the process and trigger an @error in _SQLite_Exec()
EndFunc ;==>_cb
_SQLite_Close()
_SQLite_Shutdown()
; Output:
; 1 1 2 3
; 2 5 6作为一个更简单的解决方案,我建议使用INI文件作为数据库。
[Voranol]
ProductName=Polyether Polyol
Flare=List I
Bay=1
ListPos=3
[Chem2]
ProductName=..
...然后
; Read the INI section names. This will return a 1 dimensional array.
Local $aArray = IniReadSectionNames($sFilePath)
; Check if an error occurred.
If Not @error Then
; Enumerate through the array displaying the section names.
For $i = 1 To $aArray[0]
MsgBox($MB_SYSTEMMODAL, "", "Section: " & $aArray[$i])
Next
EndIf现在,对INI文件大小的窗口有限制(32 is )。这意味着,某些Autoit函数将无法工作,如果该限制被打破。
这可以通过使用您自己的INI函数来解决:
Func _IniReadSectionNamesEx($hFile)
Local $iSize = FileGetSize($hFile) / 1024
If $iSize <= 31 Then
Local $aNameRead = IniReadSectionNames($hFile)
If @error Then Return SetError(@error, 0, '')
Return $aNameRead
EndIf
Local $aSectionNames = StringRegExp(@CRLF & FileRead($hFile) & @CRLF, '(?s)\n\s*\[(.*?)\]s*\r', 3)
If IsArray($aSectionNames) = 0 Then Return SetError(1, 0, 0)
Local $nUbound = UBound($aSectionNames)
Local $aNameReturn[$nUbound + 1]
$aNameReturn[0] = $nUbound
For $iCC = 0 To $nUBound - 1
$aNameReturn[$iCC + 1] = $aSectionNames[$iCC]
Next
Return $aNameReturn
EndFunc
Func _IniReadSectionEx($hFile, $vSection)
Local $iSize = FileGetSize($hFile) / 1024
If $iSize <= 31 Then
Local $aSecRead = IniReadSection($hFile, $vSection)
If @error Then Return SetError(@error, 0, '')
Return $aSecRead
EndIf
Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
$vSection = StringStripWS($vSection, 7)
Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
Local $nUbound = UBound($aKey)
Local $aSection[$nUBound +1][2]
$aSection[0][0] = $nUBound
For $iCC = 0 To $nUBound - 1
$aSection[$iCC + 1][0] = $aKey[$iCC]
$aSection[$iCC + 1][1] = $aValue[$iCC]
Next
Return $aSection
EndFunchttps://stackoverflow.com/questions/35668067
复制相似问题