首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库、关系查询

数据库、关系查询
EN

Stack Overflow用户
提问于 2016-02-27 09:29:37
回答 2查看 679关注 0票数 1

化学品有一个商品名称(这是通常所指的名称)和一个实际的化学品名称。我需要查一个商品名称,找到它的正确的化学名称,然后得到该化学品的性质。例如:

代码语言:javascript
复制
$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"有点乏味。我也需要能够编辑它的程序。我现在用的是:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-01 06:15:23

数据库选项的另一个替代方法是使用XML文档存储产品(化学)信息。

您可以轻松地使用XPath查询XML以获得产品名称/属性。维护文件也会相当容易。您甚至可以创建一个XML来对其进行验证,以确保您的文件在修改后仍然有效。

在AutoIt中对XML的处理可以通过几种不同的方式完成:

  • 创建MSXML对象
  • 运行像小星这样的命令行工具
  • 从命令行使用XPath/XQuery/XSLT处理器(即运行撒克逊的java )

运行像撒克逊这样的东西可能对你所需要的东西来说太过分了。

MSXML不会太糟糕,应该存在多个UDF。

我会投票给Xmlstarlet。(注:我以前从未以这种方式使用过xmlstarlet。我是撒克逊的超级粉丝,而且几乎完全使用它。对于AutoIt,我使用了MSXML和Saxon的组合;Saxon将复杂的数据转换成一个更小、更简单的子集,然后使用MSXML对该子集执行简单的xpath查询。然而,如果我要做这样的事情,我会认真地看一下xmlstarlet。)

另外,如果您的数据增长到一个XML文件没有意义,那么您可以将它分割成一个较小的文件集合;可能是单个产品。您还可能达到这样的程度:将这些文件加载到实际的XML数据库中可能是有意义的(eXistdb是一种选择)。

下面是一个简单的XML示例(模式和实例):

XSD (products.xsd)

代码语言:javascript
复制
<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)

代码语言:javascript
复制
<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

代码语言:javascript
复制
;~  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

控制台输出

代码语言:javascript
复制
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'
票数 5
EN

Stack Overflow用户

发布于 2016-02-28 11:52:00

Autoit中最好的数据库解决方案是SQLite。

如果你想像专业人士那样做,你应该使用SQLite。

代码语言:javascript
复制
#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文件作为数据库。

代码语言:javascript
复制
[Voranol]
ProductName=Polyether Polyol
Flare=List I
Bay=1
ListPos=3

[Chem2]
ProductName=..
...

然后

代码语言:javascript
复制
   ; 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函数来解决:

代码语言:javascript
复制
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
EndFunc
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35668067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档