# Batch file to extract specific line from XML file



## Ilneval (Feb 14, 2011)

What I have is multiple XML files. Each individual files on the 7th line from the bottom has the parameter or text line that I need to copy to a new, separate text file. 

Example

in my directory, I have the following files:
W001271-0181-0.xml
W001271-0182-0.xml
W001271-0183-0.xml
W001271-0184-0.xml
W001271-0185-0.xml

Each of those files are of varying length. Each has a result on the line that is 7th from the bottom on the file. I need the file to print the contents of that line from each of the individual XML's to a single text file called results.txt

I am not very good with this type of stuff, but my boss really needs it and I am the only one in the office this week. Please help


----------



## TheOutcaste (Aug 8, 2007)

Is there anything unique in these lines to identify them other than position in the file, like a specific xml tag, or text like "Final results="?
Is it always 7th from the end including blank lines? (CR/LF) For example if a file has two blank lines at the end are you counting those or ignoring them?
Any blank lines between this line and the end of the file?
Do you need the file name listed with each line?
Will the file names ever change?


----------



## Ilneval (Feb 14, 2011)

There is nothing unique that identifies this line. Yes, there are blank lines, but I am counting them in the line position. Typically it will look like the following:

Line of text
Line of text
Line I need
Blank Line
Line of text
Line of text
Blank Line
XML Code line
XML Code line

No need to have the original file name listed at all, and the file names will always change. basically we assign a process ID to each file which becomes the file name in order to have a unique file. As I mentioned, there is not set file size either. Some files could be 100 lines of text, others could be upwards of 1000 lines or more. The one constant is that the line that is 7th from the bottom is the only line of text that concerns my department. Hope that helps answer the questions.


----------



## TheOutcaste (Aug 8, 2007)

Decided to go with a VBS file. Tried a batch file with a 35000 line file and it took 25-30 seconds, with VBS takes 2-4.

This will return the same line even if the last line doesn't have a CR/LF at the end (see the screenshot) For both files, *Line 7* will be written to the output file.
Save this with a .vbs extension, like *Get7th.vbs*. Double click to run.
Specify the folder that contains the xml files in *strFolderName*
Specify the full path to the output file in *strOutName*
If you need to tweak the line it gets, adjust the *-7* shown in red.
If you don't want the popup *Completed* window, delete the last line.
To run from a batch file use this (specify path to the file if not in the same folder as the prompt):
*cscript get7th.vbs*
The completed message will be displayed in the Command Prompt window, not as a popup, in this case.

```
Const ForReading = 1, ForWriting = 2, ForAppending = 8

strFolderName = "C:\Test Dir"
strOutName = "C:\Test Dir\Logs\Output.txt"

strComputer = "."
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")

'' True will create the file if it doesn't exist, False will cause an error and abort
'' Use ForAppending to append to the output file, ForWriting to overwrite
Set objOFile = objFSO.OpenTextFile(strOutName, ForAppending, True)

Set colItems = objWMIService.ExecQuery("Associators of {Win32_Directory.Name='" & strFolderName & "'} Where ResultClass = CIM_DataFile")
For Each objItem in colItems
  If objItem.Extension = "xml" Then
    strFilename = objItem.Drive & objItem.Path & objItem.FileName & "." & objItem.Extension
    Set objFile = objFSO.OpenTextFile(strFilename, ForReading)
    Do Until objFile.AtEndOfStream
      Redim Preserve arrFileLines(i)
      arrFileLines(i) = objFile.ReadLine
      i = i + 1
    Loop
    objFile.Close
    objOFile.WriteLine arrFileLines(i-[COLOR=Red][B]7[/B][/COLOR])
  End If
Next
objOFile.Close
Wscript.Echo "Completed"
```


----------



## Ilneval (Feb 14, 2011)

I really like how the VBS script worked. I do have a small problem that I wasn't aware of going into this. If the -7 line is blank, it needs to read the -6 line instead. Is there a way to put that parameter in?


----------



## TheOutcaste (Aug 8, 2007)

Couple of ways. Depends on if the line is really blank, or has a space or two
Replace this line (5th from the bottom):
*objOFile.WriteLine arrFileLines(i-7)*
with one of these:

```
If arrFileLines(i-7) = "" Then
      objOFile.WriteLine arrFileLines(i-6)
    Else
      objOFile.WriteLine arrFileLines(i-7)
    End If
```
If that blank line might have a space or two, you can check the length. Just pick a number that will always be less then the length of a valid line.
This uses 3, so the "blank" line could be blank, one, or two spaces (or characters).

```
If Len(arrFileLines(i-7)) < 3 Then
      objOFile.WriteLine arrFileLines(i-6)
    Else
      objOFile.WriteLine arrFileLines(i-7)
    End If
```


----------



## Ilneval (Feb 14, 2011)

Excellent!! I used the first set of code, sans the ]. Worked like a charm. I have a whole program you could write for me that would make my life easier for a game I play......Used to have a program, but the game owner switched to Java and the players that had written the original data compilation program have long since disappeared.


----------

