使用vbscript检查xml节点是否存在

时间:2014-07-07 19:29:02

标签: xml vbscript xml-parsing

这是XML文件

<ECSC>
 <ATTRIBUTES>
  <some part of attribute section>
 </ATTRIBUTES>
 <SCRIPT>
  <ETXML_LINE_TABTYPE>
     <some part of script section>                 
  </ETXML_LINE_TABTYPE>
 </SCRIPT>
 <PARAMETERS>
  <ETPAR_GUIX>
     <item>
        <PNAME>I_LANG</PNAME>
        <PTYP>I</PTYP>
        <PINDEX>0003</PINDEX>
        <PDATLEN>0128</PDATLEN>
        <PINTTYP>C</PINTTYP>
        <PINTLEN>000128</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0001</SORT_LNR>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>WE20_100_STEP_1</PNAME>
        <PTYP>X</PTYP>
        <PDESC>WE20 - SAPMSEDIPARTNER - 100</PDESC>
        <PINDEX>0009</PINDEX>
        <PGROUP>SAPGUI</PGROUP>
        <XMLREF_TYP>G</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>SAPGUI</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0001</SORT_LNR>
        <PREF_NAME2>SAPGUI</PREF_NAME2>
        <VALUE>&lt;VALUE&gt;</VALUE>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>V_LANG</PNAME>
        <PTYP>V</PTYP>
        <PINDEX>0007</PINDEX>
        <PGROUP>V.01</PGROUP>
        <PDATLEN>0128</PDATLEN>
        <PINTTYP>C</PINTTYP>
        <PINTLEN>000128</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0002</SORT_LNR>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>WE20_100_STEP_2</PNAME>
        <PTYP>X</PTYP>
        <PDESC>WE20 - SAPMSEDIPARTNER - 100</PDESC>
        <PINDEX>0010</PINDEX>
        <PGROUP>SAPGUI</PGROUP>
        <XMLREF_TYP>G</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>SAPGUI</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0002</SORT_LNR>
        <PREF_NAME2>SAPGUI</PREF_NAME2>
        <VALUE>&lt;VALUE&gt;</VALUE>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>I_AGENT</PNAME>
        <PTYP>I</PTYP>
        <PINDEX>0002</PINDEX>

        <PDATLEN>0128</PDATLEN>
        <PINTTYP>C</PINTTYP>
        <PINTLEN>000128</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0003</SORT_LNR>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>WE20_100_STEP_3</PNAME>
        <PTYP>X</PTYP>
        <PDESC>WE20 - SAPMSEDIPARTNER - 100</PDESC>
        <PINDEX>0011</PINDEX>
        <PGROUP>GETGUI</PGROUP>
        <XMLREF_TYP>I</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>GETGUI</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0003</SORT_LNR>
        <PREF_NAME2>GETGUI</PREF_NAME2>
        <VALUE>&lt;VALUE&gt;</VALUE>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>I_TYPE</PNAME>
        <PTYP>I</PTYP>
        <PINDEX>0004</PINDEX>
        <PGROUP>V.04</PGROUP>
        <PDATLEN>0128</PDATLEN>
        <PINTTYP>C</PINTTYP>
        <PINTLEN>000128</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0004</SORT_LNR>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>WE20_100_STEP_4</PNAME>
        <PTYP>X</PTYP>
        <PDESC>WE20 - SAPMSEDIPARTNER - 100</PDESC>
        <PINDEX>0012</PINDEX>
        <PGROUP>GETGUI</PGROUP>
        <XMLREF_TYP>I</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>GETGUI</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0004</SORT_LNR>
        <PREF_NAME2>GETGUI</PREF_NAME2>
        <VALUE>&lt;VALUE&gt;</VALUE>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>V_AGENT</PNAME>
        <PTYP>V</PTYP>
        <PINDEX>0006</PINDEX>
        <PGROUP>I.02</PGROUP>
        <PDATLEN>0128</PDATLEN>
        <PINTTYP>C</PINTTYP>
        <PINTLEN>000128</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0005</SORT_LNR>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>WE20_100_STEP_5</PNAME>
        <PTYP>X</PTYP>
        <PDESC>WE20 - SAPMSEDIPARTNER - 100</PDESC>
        <PINDEX>0013</PINDEX>
        <PGROUP>GETGUI</PGROUP>
        <XMLREF_TYP>I</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>GETGUI</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0005</SORT_LNR>
        <PREF_NAME2>GETGUI</PREF_NAME2>
        <VALUE>&lt;VALUE&gt;</VALUE>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>V_TYPE</PNAME>
        <PTYP>V</PTYP>
        <PINDEX>0008</PINDEX>
        <PGROUP>V.03</PGROUP>
        <PDATLEN>0128</PDATLEN>
        <PINTTYP>C</PINTTYP>
        <PINTLEN>000128</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0006</SORT_LNR>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>WE20_100_STEP_6</PNAME>
        <PTYP>X</PTYP>
        <PDESC>WE20 - SAPMSEDIPARTNER - 100</PDESC>
        <PINDEX>0014</PINDEX>
        <PGROUP>SAPGUI</PGROUP>
        <XMLREF_TYP>G</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>SAPGUI</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0006</SORT_LNR>
        <PREF_NAME2>SAPGUI</PREF_NAME2>
        <VALUE>&lt;VALUE&gt;</VALUE>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>MSG_1</PNAME>
        <PTYP>X</PTYP>
        <PDESC>Rules for Message Check eCATT Command MESSAGE</PDESC>
        <PINDEX>0005</PINDEX>
        <PGROUP>MESSAGE</PGROUP>
        <XMLREF_TYP>M</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>ETMSG_DEF_TABTYPE</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0007</SORT_LNR>
        <PREF_NAME2>ETMSG_DEF_TABTYPE</PREF_NAME2>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>E_MSG_1</PNAME>
        <PTYP>X</PTYP>
        <PDESC>Collected Messages Before ENDMESSAGE</PDESC>
        <PINDEX>0001</PINDEX>
        <PGROUP>ENDMESSAGE</PGROUP>
        <XMLREF_TYP>N</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>ETMSG_RES_TABTYPE</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0008</SORT_LNR>
        <PREF_NAME2>ETMSG_RES_TABTYPE</PREF_NAME2>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
     <item>
        <PNAME>ZX_FI_FP_0569_MS07_COAS_FB_1</PNAME>
        <PTYP>X</PTYP>
        <PDESC>TF_FI_FP_FI_0569_MS07_CO_Search_Help_Internal_Orders_vTD0_1_</PDESC>
        <PINDEX>0015</PINDEX>
        <PGROUP>REF</PGROUP>
        <XMLREF_TYP>R</XMLREF_TYP>
        <PSTRUC_TYP>T</PSTRUC_TYP>
        <PREF_NAME>ZX_FI_FP_0569_MS07_COAS_FB01</PREF_NAME>
        <PDATLEN>0000</PDATLEN>
        <PINTLEN>000000</PINTLEN>
        <PDECIMALS>000000</PDECIMALS>
        <SORT_LNR>0009</SORT_LNR>
        <PREF_NAME2>ZX_FI_FP_0569_MS07_COAS_FB01</PREF_NAME2>
        <VAL_TYPE>T</VAL_TYPE>
        <TAB_INDEX>0</TAB_INDEX>
     </item>
  </ETPAR_GUIX>

从上面的XML文件中我们要验证以下条件:

1)来自<PARAMETERS>代码如果<PNAME>代码的前两个字母以&#34开头,我_&#34;或者&#34; V _&#34;或者&#34; E _&#34;然后它的相应<PTYP><PGROUP> nodetext应该以#34; I&#34;开头。或者&#34; V&#34;或者&#34; E&#34;分别

2)来自<PARAMETERS>标记如果<PNAME>中的任何一个没有对应的<PGROUP>那么VB脚本应该显示错误,在这种情况下我们必须跳过检查第一个条件{{ 1}}节点只显示错误&#34; <PGROUP>&#34;

不存在<PGROUP>个节点

这是我试过的vbscript:

<PNAME>

请帮帮我。提前谢谢。

2 个答案:

答案 0 :(得分:1)

使用带有selectNodes的XPath来识别无效的item元素,然后遍历无效节点以显示错误消息:

Option Explicit

Dim oFS      : Set oFS      = CreateObject("Scripting.FileSystemObject")
Dim sFSpec   : sFSpec       = oFS.GetAbsolutePathName("C:\doc.xml")
Dim objMSXML : Set objMSXML = CreateObject("Msxml2.DOMDocument")
objMSXML.setProperty "SelectionLanguage", "XPath"
objMSXML.async = False
objMSXML.load sFSpec
objMSXML.validateOnParse = True

FindMissingPgroups objMSXML
FindInvalidPtyps objMSXML
FindInvalidPGroups objMSXML

Sub FindMissingPgroups(doc)
    Dim query, items, item, pname

    query = "/ECSC/PARAMETERS/ETPAR_GUIX/item[not(PGROUP)]"
    Set items = doc.selectNodes(query)

    For Each item In items
        Set pname = item.selectSingleNode("PNAME")
        MsgBox "Missing PGROUP for " & pname.text
    Next ' item
End Sub

Sub FindInvalidPtyps(doc)
    Dim query, items, item, pname, ptyp

    query = query & "/ECSC/PARAMETERS/ETPAR_GUIX/item[PGROUP]["
    query = query & "  (starts-with(PNAME, 'I_') and not(starts-with(PTYP, 'I'))) or "
    query = query & "  (starts-with(PNAME, 'V_') and not(starts-with(PTYP, 'V'))) or "
    query = query & "  (starts-with(PNAME, 'E_') and not(starts-with(PTYP, 'E')))"
    query = query & "]"

    Set items = doc.selectNodes(query)

    For Each item In items
        Set pname = item.selectSingleNode("PNAME")
        Set ptyp = item.selectSingleNode("PTYP")
        MsgBox "Invalid PTYP (" & ptyp.text & ") for " & pname.text
    Next ' item
End Sub

Sub FindInvalidPgroups(doc)
    Dim query, items, item, pname, pgroup

    query = query & "/ECSC/PARAMETERS/ETPAR_GUIX/item[PGROUP]["
    query = query & "  (starts-with(PNAME, 'I_') and not(starts-with(PGROUP, 'I'))) or "
    query = query & "  (starts-with(PNAME, 'V_') and not(starts-with(PGROUP, 'V'))) or "
    query = query & "  (starts-with(PNAME, 'E_') and not(starts-with(PGROUP, 'E')))"
    query = query & "]"

    Set items = doc.selectNodes(query)

    For Each item In items
        Set pname = item.selectSingleNode("PNAME")
        Set pgroup = item.selectSingleNode("PGROUP")
        MsgBox "Invalid PGROUP (" & pgroup.text & ") for " & pname.text
    Next ' item
End Sub

一些注意事项:

  • 始终在每个脚本的顶部使用Option Explicit。它将在未来为您节省麻烦。
  • 我将测试分成三组而不是两组。分别测试PTYP和PGROUP更容易。
  • 请注意,无效PTYP和PGROUP的测试包含谓词[PGROUP]。这样可以确保我们只检查具有PGROUP的项目(这是条件2要求的一部分)。

答案 1 :(得分:0)

您可以使用两个For Each循环,每个规则一个循环。对于第二条规则,请选择所有<PNAME>而不添加相应的<PGROUP>,并显示错误消息,如我在the other question中所述。

对于第一条规则,请选择<item>所有<PGROUP>并验证它们:

Set nodesWithPgroup = objMSXML.documentElement.selectNodes("/ECSC/PARAMETERS/ETPAR_GUIX/item[PGROUP]")
For Each item in nodesWithPgroup
  myPNAME = item.SelectSingleNode("PNAME").text
  myPTYP = item.SelectSingleNode("PTYP").text
  myPGROUP = item.SelectSingleNode("PGROUP").text
  code = Left(myPNAME, 1)
  If (Left(myPNAME, 2) = code & "_") Then
    If (Left(myPTYP, 1) <> code Or Left(myPGROUP, 1) <> code) Then
        msgbox(myPNAME & " is not valid.")
    End If
  End If
Next