VBS读取xml的问题

shanyuhuang 2016-04-29 06:16:22
本人小白,不太了解xml,vba也只是略懂,现有下面的课题,望各位大神不吝赐教

现有客户如下VBS代码:
根据输入参数:pIn01,pIn02,pIn03分别设置输出参数pOut01,pOut02,pOut01

Select Case pIn01
Case "A01" :
If pIn02 = 0 Then
If pIn03 = 2 Then
pOut01 = "X01"
pOut02 = "Y01"
pOut03 = 0
Else
pOut03 = 1
End If
Else
pOut03 = 2
End If

Case "B01" :
If pIn02 = 1 Then
If pIn03 = 3 Then
pOut01 = "X02"
pOut02 = "Y02"
pOut03 = 0
Else
pOut03 = 1
End If
Else
pOut03 = 2
End If

Case "C01" :
If pIn02 = 0 Then
If pIn03 = 3 Or pIn03 = 4 Then
pOut01 = "X03"
pOut02 = "Y03"
pOut03 = 0
Else
pOut03 = 1
End If
Else
pOut03 = 2
End If

Case "D01" :
If pIn02 = 0 Then
If pIn03 = 2 Then
pOut01 = "X04"
pOut02 = "Y04"
pOut03 = 0
Else
pOut03 = 1
End If
Else
If pIn03 = 4 Then
pOut01 = "X05"
pOut02 = "Y05"
pOut03 = 0
Else
pOut03 = 1
End If
End If

Case "E01" :
If pIn02 = 0 Then
pOut03 = 2
Else
If pIn03 = 4 Then
pOut01 = "X06"
pOut02 = "Y06"
pOut03 = 0
Else
pOut03 = 1
End If
End If

Case "F01" :
If pIn02 = 0 Then
If pIn03 = 3 Then
If pIn04 = "NAME01" Then
pOut01 = "X07"
pOut02 = "Y07"
pOut03 = 0
ELSE
pOut01 = "X08"
pOut02 = "Y08"
pOut03 = 0
END IF
Else
pOut03 = 1
End If
Else
pOut03 = 2
End If

Case Else :
pOut03 = 2
End Select


现在客户觉得这种写法太傻,希望把这个对应关系以xml形式保存,然后读入xml根据输入参数来取得输出参数的值
以后如果有增加pIn01值的情况下,只需要增加xml的内容,无需改动代码。

请问:
1.xml该如何设计?(我只知道xml能保存固定信息,不知道如何在xml中保存if关系)
2.vbs如何读取xml?

谢谢各位了!
...全文
260 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
shanyuhuang 2016-05-12
  • 打赏
  • 举报
回复
引用 10 楼 Tiger_Zhao 的回复:
[Quote=引用 9 楼 shanyuhuang 的回复:]1.我知道VBS里面需要把匹配度最高的最先判断(写成最外层的if),但是xml为什么要匹配度小的排在前面? 2.可能您没有看完整的case文,最后的case分支里还有个pIn04,其实pIn04的处理才是我觉得麻烦的地方, pIn01~pIn03按照您现在提供的方案是完全没问题的,但是pIn04不仅仅是值匹配的问题,还有一个需不需要判的问题, 还请您能不吝赐教[/Quote] 1.selectSingleNode()是相等匹配,找到一个满足条件的就返回。当然要把匹配条件最多的放在前面。 你自己交换次序试试就知道了。 2.不能保证所有的case分支都肯定能转xml的。 做不到就是做不到,就像现在物流很发达,你还是不能让快递小哥给你送一吨煤吧!
感谢回答。 第一个试了下的确如此 第二个我也感觉是做不到,但是对于xml不太熟悉所以还是确认一下。
Tiger_Zhao 2016-05-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 shanyuhuang 的回复:]1.我知道VBS里面需要把匹配度最高的最先判断(写成最外层的if),但是xml为什么要匹配度小的排在前面? 2.可能您没有看完整的case文,最后的case分支里还有个pIn04,其实pIn04的处理才是我觉得麻烦的地方, pIn01~pIn03按照您现在提供的方案是完全没问题的,但是pIn04不仅仅是值匹配的问题,还有一个需不需要判的问题, 还请您能不吝赐教[/Quote] 1.selectSingleNode()是相等匹配,找到一个满足条件的就返回。当然要把匹配条件最多的放在前面。 你自己交换次序试试就知道了。 2.不能保证所有的case分支都肯定能转xml的。 做不到就是做不到,就像现在物流很发达,你还是不能让快递小哥给你送一吨煤吧!
shanyuhuang 2016-05-10
  • 打赏
  • 举报
回复
引用 4 楼 Tiger_Zhao 的回复:
用XML更傻! 下面是 x.xml,只写了 A01 和 B01 两部分,为了 XPath 方便,匹配度小的(vbs 中 Else 部分)要排在前面。
<?xml version="1.0"?>
<Table>
  <Row>
    <pIn01>A01</pIn01>
    <pIn02></pIn02>
    <pIn03></pIn03>
    <pOut01></pOut01>
    <pOut02></pOut02>
    <pOut03>2</pOut03>
  </Row>
  <Row>
    <pIn01>A01</pIn01>
    <pIn02>0</pIn02>
    <pIn03></pIn03>
    <pOut01></pOut01>
    <pOut02></pOut02>
    <pOut03>1</pOut03>
  </Row>
  <Row>
    <pIn01>A01</pIn01>
    <pIn02>0</pIn02>
    <pIn03>2</pIn03>
    <pOut01>X01</pOut01>
    <pOut02>Y01</pOut02>
    <pOut03>0</pOut03>
  </Row>
  <Row>
    <pIn01>B01</pIn01>
    <pIn02></pIn02>
    <pIn03></pIn03>
    <pOut01></pOut01>
    <pOut02></pOut02>
    <pOut03>2</pOut03>
  </Row>
  <Row>
    <pIn01>B01</pIn01>
    <pIn02>1</pIn02>
    <pIn03></pIn03>
    <pOut01></pOut01>
    <pOut02></pOut02>
    <pOut03>1</pOut03>
   </Row>
  <Row>
    <pIn01>B01</pIn01>
    <pIn02>1</pIn02>
    <pIn03>3</pIn03>
    <pOut01>X02</pOut01>
    <pOut02>Y02</pOut02>
    <pOut03>0</pOut03>
  </Row>
</Table>
Dim pIn01
Dim pIn02
Dim pIn03
Dim pOut01
Dim pOut02
Dim pOut03

Call Main()

Sub Main()
    pIn01 = "A01"
    pIn02 = 1
    pIn03 = 3
    
    Query
    
    MsgBox "pOut01=" & pOut01 & vbCrLf & _
           "pOut02=" & pOut02 & vbCrLf & _
           "pOut03=" & pOut03
           
End Sub

Sub Query()
    Dim doc
    Dim node
    
    Set doc = WScript.CreateObject("MSXML2.DOMDocument")
    doc.Load ("x.xml") '<- 自己补齐路径'
    
    Set node = doc.selectSingleNode("/Table/Row[(pIn01=""" & pIn01 & """) and (pIn02=""" & pIn02 & """) and (pIn03=""" & pIn03 & """)]")
    If node Is Nothing Then
        Set node = doc.selectSingleNode("/Table/Row[(pIn01=""" & pIn01 & """) and (pIn02=""" & pIn02 & """)]")
        If node Is Nothing Then
            Set node = doc.selectSingleNode("/Table/Row[pIn01=""" & pIn01 & """]")
        End If
    End If
    
    pOut01 = node.selectSingleNode("pOut01").Text
    pOut02 = node.selectSingleNode("pOut02").Text
    pOut03 = node.selectSingleNode("pOut03").Text
End Sub
万分感谢回答,但是还有2个问题希望能解答: 1.我知道VBS里面需要把匹配度最高的最先判断(写成最外层的if),但是xml为什么要匹配度小的排在前面? 2.可能您没有看完整的case文,最后的case分支里还有个pIn04,其实pIn04的处理才是我觉得麻烦的地方, pIn01~pIn03按照您现在提供的方案是完全没问题的,但是pIn04不仅仅是值匹配的问题,还有一个需不需要判的问题, 还请您能不吝赐教 谢谢!
shanyuhuang 2016-05-04
  • 打赏
  • 举报
回复
感谢楼上各位,尤其是四楼的回答
of123 2016-05-03
  • 打赏
  • 举报
回复
未必,将 xml 直接作为 Jet Engine 的外部数据库来访问,直接查询就好了。哪里还要读取和分析文本?
Tiger_Zhao 2016-05-03
  • 打赏
  • 举报
回复
用XML更傻!
下面是 x.xml,只写了 A01 和 B01 两部分,为了 XPath 方便,匹配度小的(vbs 中 Else 部分)要排在前面。
<?xml version="1.0"?>
<Table>
<Row>
<pIn01>A01</pIn01>
<pIn02></pIn02>
<pIn03></pIn03>
<pOut01></pOut01>
<pOut02></pOut02>
<pOut03>2</pOut03>
</Row>
<Row>
<pIn01>A01</pIn01>
<pIn02>0</pIn02>
<pIn03></pIn03>
<pOut01></pOut01>
<pOut02></pOut02>
<pOut03>1</pOut03>
</Row>
<Row>
<pIn01>A01</pIn01>
<pIn02>0</pIn02>
<pIn03>2</pIn03>
<pOut01>X01</pOut01>
<pOut02>Y01</pOut02>
<pOut03>0</pOut03>
</Row>
<Row>
<pIn01>B01</pIn01>
<pIn02></pIn02>
<pIn03></pIn03>
<pOut01></pOut01>
<pOut02></pOut02>
<pOut03>2</pOut03>
</Row>
<Row>
<pIn01>B01</pIn01>
<pIn02>1</pIn02>
<pIn03></pIn03>
<pOut01></pOut01>
<pOut02></pOut02>
<pOut03>1</pOut03>
</Row>
<Row>
<pIn01>B01</pIn01>
<pIn02>1</pIn02>
<pIn03>3</pIn03>
<pOut01>X02</pOut01>
<pOut02>Y02</pOut02>
<pOut03>0</pOut03>
</Row>
</Table>

Dim pIn01
Dim pIn02
Dim pIn03
Dim pOut01
Dim pOut02
Dim pOut03

Call Main()

Sub Main()
pIn01 = "A01"
pIn02 = 1
pIn03 = 3

Query

MsgBox "pOut01=" & pOut01 & vbCrLf & _
"pOut02=" & pOut02 & vbCrLf & _
"pOut03=" & pOut03

End Sub

Sub Query()
Dim doc
Dim node

Set doc = WScript.CreateObject("MSXML2.DOMDocument")
doc.Load ("x.xml") '<- 自己补齐路径'

Set node = doc.selectSingleNode("/Table/Row[(pIn01=""" & pIn01 & """) and (pIn02=""" & pIn02 & """) and (pIn03=""" & pIn03 & """)]")
If node Is Nothing Then
Set node = doc.selectSingleNode("/Table/Row[(pIn01=""" & pIn01 & """) and (pIn02=""" & pIn02 & """)]")
If node Is Nothing Then
Set node = doc.selectSingleNode("/Table/Row[pIn01=""" & pIn01 & """]")
End If
End If

pOut01 = node.selectSingleNode("pOut01").Text
pOut02 = node.selectSingleNode("pOut02").Text
pOut03 = node.selectSingleNode("pOut03").Text
End Sub

of123 2016-05-03
  • 打赏
  • 举报
回复
那就自己另存一个 xml 文件。 把上面的数据表改成有 Tab 分隔的格式
pIn01	pIn02	pIn03	pOut01	pOut02	pOut01
A	0	1	X1	Y1	Z1
B	0	2	X2	Y2	Z2
C	0	3	X3	Y3	Z3
D	1	1	X4	Y4	Z4
E	1	2	X5	Y5	Z5
F	1	3	X6	Y6	Z6
你打开 Excel,将上面数据复制粘贴到一个表中。 然后,另存为“XML 表格(*.xml)“。你访问这个自用工具表格就可以了。
赵4老师 2016-05-03
  • 打赏
  • 举报
回复
傻人有傻福
Tiger_Zhao 2016-05-03
  • 打赏
  • 举报
回复
我是说他原先的分支判断转xml不合适。
比如输入:{A01,0,3}
程序又不能预先知道{A01,0,2}不匹配,只能匹配{A01,0,},写不出唯一确定的 XPath;
结果要靠<Row>的次序来进行匹配,这不符合 xml 数据的次序无关规则。
shanyuhuang 2016-05-02
  • 打赏
  • 举报
回复
感谢楼上解答 但是xml是客户指定的,我们无权修改数据库的。
vansoft 2016-04-30
  • 打赏
  • 举报
回复
二维表啊。 pIn01,pIn02,pIn03,pOut01,pOut02,pOut01 A 0 1 X1 Y1 Z1 B 0 2 X2 Y2 Z2 C 0 3 X3 Y3 Z3 D 1 1 X4 Y4 Z4 E 1 2 X5 Y5 Z5 F 1 3 X6 Y6 Z6 是不是这样? 直接用数据库啊。一个SQL语句就可以查出来对应的。

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧