none
Требуется VBS скрипт для анализа xml-файлов в каталоге. RRS feed

  • Вопрос

  • Господа!

    В VBS не силен. Требуется VBS скрипт, который бы подсчитывал количество элементов <VALUE.OBJECT> в xml-файлах в определенном каталоге и выводил следующий список:

    имя_файла дата_создания_файла количество_элементов_<VALUE.OBJECT>

    имя_файла дата_создания_файла количество_элементов_<VALUE.OBJECT>

    имя_файла дата_создания_файла количество_элементов_<VALUE.OBJECT>

    Пример xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE CIM [
    <!ELEMENT CIM (DECLARATION?)>
    <!ATTLIST CIM
      CIMVERSION CDATA #IMPLIED
      DTDVERSION CDATA #IMPLIED>
    <!ELEMENT DECLARATION (DECLGROUP*)>
    <!ELEMENT DECLGROUP (VALUE.OBJECT*)>
    <!ELEMENT VALUE.OBJECT (INSTANCE?)>
    <!ELEMENT INSTANCE (PROPERTY*)>
    <!ATTLIST INSTANCE CLASSNAME CDATA #IMPLIED>
    <!ELEMENT PROPERTY (VALUE?)>
    <!ATTLIST PROPERTY
      CLASSORIGIN CDATA #IMPLIED
      NAME CDATA #IMPLIED
      PROPAGATED CDATA #IMPLIED
      TYPE CDATA #IMPLIED>
    <!ELEMENT VALUE (#PCDATA)>
    ]>
    <CIM CIMVERSION="2.0" DTDVERSION="2.2">
      <DECLARATION>
        <DECLGROUP>
          <VALUE.OBJECT>
            <INSTANCE CLASSNAME="IN_PROGRESS">
              <PROPERTY NAME="ID" TYPE="string">
                <VALUE>1</VALUE>
              </PROPERTY>
              <PROPERTY NAME="СБ_ID" TYPE="string">
                <VALUE>925233</VALUE>
              </PROPERTY>
              <PROPERTY NAME="ФЛАГ" TYPE="string">
                <VALUE>1</VALUE>
              </PROPERTY>
              <PROPERTY NAME="CLOSE" TYPE="string">
                <VALUE>0</VALUE>
              </PROPERTY>
            </INSTANCE>
          </VALUE.OBJECT>
        </DECLGROUP>
      </DECLARATION>
      <DECLARATION>
        <DECLGROUP>
          <VALUE.OBJECT>
            <INSTANCE CLASSNAME="IN_PROGRESS">
              <PROPERTY NAME="ID" TYPE="string">
                <VALUE>2</VALUE>
              </PROPERTY>
              <PROPERTY NAME="СБ_ID" TYPE="string">
                <VALUE>1047422</VALUE>
              </PROPERTY>
              <PROPERTY NAME="ФЛАГ" TYPE="string">
                <VALUE>1</VALUE>
              </PROPERTY>
              <PROPERTY NAME="CLOSE" TYPE="string">
                <VALUE>0</VALUE>
              </PROPERTY>
            </INSTANCE>
          </VALUE.OBJECT>
        </DECLGROUP>
      </DECLARATION>
      <DECLARATION>
        <DECLGROUP>
          <VALUE.OBJECT>
            <INSTANCE CLASSNAME="IN_PROGRESS">
              <PROPERTY NAME="ID" TYPE="string">
                <VALUE>3</VALUE>
              </PROPERTY>
              <PROPERTY NAME="СБ_ID" TYPE="string">
                <VALUE>1048661</VALUE>
              </PROPERTY>
              <PROPERTY NAME="ФЛАГ" TYPE="string">
                <VALUE>1</VALUE>
              </PROPERTY>
              <PROPERTY NAME="CLOSE" TYPE="string">
                <VALUE>0</VALUE>
              </PROPERTY>
            </INSTANCE>
          </VALUE.OBJECT>
        </DECLGROUP>
      </DECLARATION>
      <DECLARATION>
        <DECLGROUP>
          <VALUE.OBJECT>
            <INSTANCE CLASSNAME="IN_PROGRESS">
              <PROPERTY NAME="ID" TYPE="string">
                <VALUE>4</VALUE>
              </PROPERTY>
              <PROPERTY NAME="СБ_ID" TYPE="string">
                <VALUE>1048690</VALUE>
              </PROPERTY>
              <PROPERTY NAME="ФЛАГ" TYPE="string">
                <VALUE>1</VALUE>
              </PROPERTY>
              <PROPERTY NAME="CLOSE" TYPE="string">
                <VALUE>0</VALUE>
              </PROPERTY>
            </INSTANCE>
          </VALUE.OBJECT>
        </DECLGROUP>
      </DECLARATION>
    </CIM>

    29 января 2013 г. 9:34

Ответы

  • Как-то так:

    Dim objRegExp, objFS, objFolderItems, strTest, strPath, strList
    strPath = "D:\Temp"
    Set objRegExp = CreateObject("VBScript.RegExp")
    objRegExp.Global = True
    objRegExp.IgnoreCase = True
    objRegExp.Pattern = "<VALUE.OBJECT>"
    Set objFS = CreateObject("Scripting.FileSystemObject")
    Set objFolderItems = CreateObject("Shell.Application").NameSpace(strPath).Items
    objFolderItems.Filter 64 + 128, "*.xml"
    If objFolderItems.Count > 0 Then
        On Error Resume Next
        For Each objItem In objFolderItems
            strTest = objFS.OpenTextFile(objItem.Path, 1).ReadAll
            If Err.Number = 0 Then
                strList = strList & objItem.Name & " " & _
                        FormatDateTime(objFS.GetFile(objItem.Path).DateCreated, 2) & " " & _
                        objRegExp.Execute(strTest).Count & vbNewLine
            Else
                Err.Clear
            End If
        Next
        WScript.Echo strList
    Else
        WScript.Echo "Не найдено ни одного XML-файла."
    End If
    Set objFolderItems = Nothing
    Set objFS = Nothing
    Set objRegExp = Nothing
    WScript.Quit 0


    • Изменено DmitriiV 29 января 2013 г. 11:44
    • Помечено в качестве ответа KazunEditor 29 января 2013 г. 12:10
    29 января 2013 г. 11:41
  • Нет такой возможности.
    • Помечено в качестве ответа Shurepsky 29 января 2013 г. 13:14
    29 января 2013 г. 13:13
  • Впрочем, можно ускорить обработку, добавив соответствующее условие в код цикла:
    Dim objRegExp, objFS, objFolderItems, strTest
    Dim strNow, strDateCreated
    Set objRegExp = CreateObject("VBScript.RegExp")
    objRegExp.Global = True
    objRegExp.IgnoreCase = True
    objRegExp.Pattern = "<VALUE.OBJECT>"
    Set objFS = CreateObject("Scripting.FileSystemObject")
    Set objFolderItems = CreateObject("Shell.Application").NameSpace("D:\Temp").Items
    objFolderItems.Filter 64 + 128, "*.xml"
    If objFolderItems.Count > 0 Then
        On Error Resume Next
        strNow = FormatDateTime(Date, 2)
        For Each objItem In objFolderItems
            strDateCreated = FormatDateTime(objFS.GetFile(objItem.Path).DateCreated, 2)
            If strNow = strDateCreated Then
                strTest = objFS.OpenTextFile(objItem.Path, 1).ReadAll
                If Err.Number = 0 Then
                    strList = strList & objItem.Name & " " & strDateCreated & " " & _
                                objRegExp.Execute(strTest).Count & vbNewLine
                Else
                    Err.Clear
                End If
            End If
        Next
        WScript.Echo strList
    Else
        WScript.Echo "Не найдено ни одного XML-файла."
    End If
    Set objFolderItems = Nothing
    Set objFS = Nothing
    Set objRegExp = Nothing
    WScript.Quit 0


    • Помечено в качестве ответа Shurepsky 31 января 2013 г. 10:53
    29 января 2013 г. 13:27

Все ответы

  • в поше парой строчек можно реализовать, чем он не приглянулся?
    29 января 2013 г. 10:10
  • К сожалению с PowerShell не работал.
    29 января 2013 г. 10:17
  • Как-то так:

    Dim objRegExp, objFS, objFolderItems, strTest, strPath, strList
    strPath = "D:\Temp"
    Set objRegExp = CreateObject("VBScript.RegExp")
    objRegExp.Global = True
    objRegExp.IgnoreCase = True
    objRegExp.Pattern = "<VALUE.OBJECT>"
    Set objFS = CreateObject("Scripting.FileSystemObject")
    Set objFolderItems = CreateObject("Shell.Application").NameSpace(strPath).Items
    objFolderItems.Filter 64 + 128, "*.xml"
    If objFolderItems.Count > 0 Then
        On Error Resume Next
        For Each objItem In objFolderItems
            strTest = objFS.OpenTextFile(objItem.Path, 1).ReadAll
            If Err.Number = 0 Then
                strList = strList & objItem.Name & " " & _
                        FormatDateTime(objFS.GetFile(objItem.Path).DateCreated, 2) & " " & _
                        objRegExp.Execute(strTest).Count & vbNewLine
            Else
                Err.Clear
            End If
        Next
        WScript.Echo strList
    Else
        WScript.Echo "Не найдено ни одного XML-файла."
    End If
    Set objFolderItems = Nothing
    Set objFS = Nothing
    Set objRegExp = Nothing
    WScript.Quit 0


    • Изменено DmitriiV 29 января 2013 г. 11:44
    • Помечено в качестве ответа KazunEditor 29 января 2013 г. 12:10
    29 января 2013 г. 11:41
  • А как добавить фильтр, чтобы подсчет велся только по файлам за текущую дату? Файлов много, скрипт долго отрабатывает.
    • Изменено Shurepsky 29 января 2013 г. 12:49
    29 января 2013 г. 12:28
  • Нет такой возможности.
    • Помечено в качестве ответа Shurepsky 29 января 2013 г. 13:14
    29 января 2013 г. 13:13
  • Впрочем, можно ускорить обработку, добавив соответствующее условие в код цикла:
    Dim objRegExp, objFS, objFolderItems, strTest
    Dim strNow, strDateCreated
    Set objRegExp = CreateObject("VBScript.RegExp")
    objRegExp.Global = True
    objRegExp.IgnoreCase = True
    objRegExp.Pattern = "<VALUE.OBJECT>"
    Set objFS = CreateObject("Scripting.FileSystemObject")
    Set objFolderItems = CreateObject("Shell.Application").NameSpace("D:\Temp").Items
    objFolderItems.Filter 64 + 128, "*.xml"
    If objFolderItems.Count > 0 Then
        On Error Resume Next
        strNow = FormatDateTime(Date, 2)
        For Each objItem In objFolderItems
            strDateCreated = FormatDateTime(objFS.GetFile(objItem.Path).DateCreated, 2)
            If strNow = strDateCreated Then
                strTest = objFS.OpenTextFile(objItem.Path, 1).ReadAll
                If Err.Number = 0 Then
                    strList = strList & objItem.Name & " " & strDateCreated & " " & _
                                objRegExp.Execute(strTest).Count & vbNewLine
                Else
                    Err.Clear
                End If
            End If
        Next
        WScript.Echo strList
    Else
        WScript.Echo "Не найдено ни одного XML-файла."
    End If
    Set objFolderItems = Nothing
    Set objFS = Nothing
    Set objRegExp = Nothing
    WScript.Quit 0


    • Помечено в качестве ответа Shurepsky 31 января 2013 г. 10:53
    29 января 2013 г. 13:27
  • Скрипт отлично работает. Сейчас понадобилось ему вместо D:\Temp передать значение environment variable DIRECTORY. Этой переменной присваивается путь до каталога с файлами. Как это можно реализовать в скрипте?
    5 февраля 2013 г. 10:38
  • Не знаю переменной среды окружения, именуемой DIRECTORY. Покажите пример пути и укажите версии ОС, на которых должен работать сценарий.
    5 февраля 2013 г. 11:42
  • Я для примера написал. Она задается вручную в сторонней системе, которая запускает скрипт. Работает все на Win2008. Реализовал следующим образом (не судите за кривость:)):

    cmd файл:

    @echo off
    cscript.exe /nologo "script.vbs" %FILE_DIRECTORY% 

    сам скрипт:

    Dim objRegExp, objFS, objFolderItems, strTest
    Dim strNow, strDateCreated
    Set objRegExp = CreateObject("VBScript.RegExp")
    objRegExp.Global = True
    objRegExp.IgnoreCase = True
    objRegExp.Pattern = "<VALUE.OBJECT>"
    objArgs = WScript.Arguments
    Set path_to_file=objArgs(0)
    Set objFS = CreateObject("Scripting.FileSystemObject")
    Set objFolderItems = CreateObject("Shell.Application").NameSpace(path_to_file).Items 
    objFolderItems.Filter 64 + 128, "*.xml"
    If objFolderItems.Count > 0 Then
        On Error Resume Next
        strNow = FormatDateTime(Date, 2)
        For Each objItem In objFolderItems
            strDateCreated = FormatDateTime(objFS.GetFile(objItem.Path).DateCreated, 2)
            If strNow = strDateCreated Then
                strTest = objFS.OpenTextFile(objItem.Path, 1).ReadAll
                If Err.Number = 0 Then
                    strList = strList & objItem.Name & " " & strDateCreated & " " & _
                                objRegExp.Execute(strTest).Count & vbNewLine
                Else
                    Err.Clear
                End If
            End If
        Next
        WScript.Echo strList
    Else
        WScript.Echo "Не найдено ни одного XML-файла."
    End If
    Set objFolderItems = Nothing
    Set objFS = Nothing
    Set objRegExp = Nothing
    WScript.Quit 0



    • Изменено Shurepsky 5 февраля 2013 г. 13:26
    5 февраля 2013 г. 13:24