Create multiple PDF files from one input PDF file, split using bookmarks - vb.net
I've been working on a VB.NET project to dynamically create report packs in PDF format using a SQL database and a number of input PDF templates. To cut a long story short, due to the way that Business Objects creates the input files it will be much more efficient to allow input of compiled PDF reports rather than individual report template pages. In order for this to work however, we would need to split the input PDF files into sections using the Bookmarks created by BOBJ. We are not sure how many pages will be in the range of each bookmark but require a consistent naming convention of the split files so that the next part of the process can pick the correct templates up and merge them in the required combinations.
The second part of this process is designed and working well using a .Net library called PDFSHARP. I have used the samples on their website to write some code which splits an input PDF file into one section per page of the input file, but do not understand how to split it using the bookmarks.
If I could understand how to parse the PDF and read in the meta data for the bookmarks which contain the start page and end page and the name of the bookmark then I think I could finish it.
An example of the input PDF format is here:
https://drive.google.com/open?id=0B0GZGW6CFCI-UWY2WGRvV0dQSWZSNnNOWlp4R21zbFVPZDBn
There are 5 bookmarks (TID01, TID02 ...) and 6 pages. Section TID04 would have two pages output.
The file names I would need would be in the format of "ExamplePDF_TID01.pdf"
Any help to move forward would be greatly appreciated. - Looking on the wiki for the project it seems that it isn't very active any more and whilst other people have asked questions about this in the past there aren't any answers that I can find.
Code to Split by Page:
Sub Splitfiles()
Dim inputdir As String = "O:\Transformation\Standardisation\Input PDFs"
Dim outputdir As String = "O:\Transformation\Standardisation\Input PDFs\output\"
'inputdir = folder path containing input files
Dim fileEntries As String() = Directory.GetFiles(inputdir)
Dim filename As String
Dim pdfpage As PdfPage
Dim ccid As String
Dim pageid As Integer
Dim outputfilename As String
For Each filename In fileEntries
Dim importdoc As PdfDocument = PdfReader.Open(filename, PdfSharp.Pdf.IO.PdfDocumentOpenMode.Import)
Dim count As Integer = importdoc.PageCount
Dim x = 0
Do Until x = count
Dim outputdoc As PdfDocument = New PdfDocument
pdfpage = importdoc.Pages(x)
outputdoc.AddPage(pdfpage)
ccid = Strings.Right(filename, Len(filename) - Len(inputdir)) 'expand this to find CC ID
ccid = Strings.Left(ccid, Len(ccid) - 4)
pageid = x
outputfilename = outputdir & ccid & "_" & pageid & ".pdf"
outputdoc.Save(outputfilename)
x = x + 1
Loop
Next
End Sub
And the code I started to split by bookmark but couldn't finish:
Sub SplitPDFByBookmark()
Dim inputfile As String = "O:\Transformation\Standardisation\Input PDFs\Business Sub Area Report - Project Management - FY16_FP02 - 17062016_0709.PDF"
Dim outputdir As String = "O:\Transformation\Standardisation\Input PDFs\output\"
'inputdir = folder path containing input files
'Dim fileEntries As String() = Directory.GetFiles(inputdir)
Dim filename As String
Dim pdfpage As PdfPage
Dim ccid As String
Dim pageid As Integer
Dim outputfilename As String
filename = inputfile
'For Each filename In fileEntries
Dim importdoc As PdfDocument = PdfReader.Open(filename, PdfSharp.Pdf.IO.PdfDocumentOpenMode.Import)
Dim count As Integer = importdoc.PageCount
Dim x = 0
For Each bookmark In importdoc.Outlines
Dim outputdoc As PdfDocument = New PdfDocument
pdfpage = importdoc.Pages(importdoc.Outlines.)
outputdoc.AddPage(pdfpage)
pageid = x
outputfilename = outputdir & "OutputFile_" & pageid & ".pdf"
outputdoc.Save(outputfilename)
x = x + 1
Next
'Next
End Sub
Thanks in advance for your help!
Related
Why would my Libreoffice Basic script fail to make PDFs with working links?
I've written a script using Libreoffice Basic that pulls data from a calc file and puts it in a writer doc and then exports the doc as a PDF. While that works there is an unwanted effect, none of the links work in the PDF. If I manually export the PDF, the links work. How do I alter the script so that the PDFs created will have working links too? Script follows (links to example PDFs at the end): REM Making example pdfs based on writer file while pulling data from a calc file Dim strPath As String Dim objWriterDoc As Object Dim objCalcDoc As Object Dim objCalcSheet as Object Dim objCalcCellForID as Object Dim objCalcCellForName as Object Dim rg as Object Dim lngRows as Long Dim args() Dim PDFargs(1) As New "com.sun.star.beans.PropertyValue" Dim Watermarkargs(4) As New "com.sun.star.beans.PropertyValue" REM set PDF export args PDFargs(0).Name = "FilterName" PDFargs(0).Value = "writer_pdf_Export" PDFargs(1).Name = "FilterData" PDFargs(1).Value = Array(Array("UseLosslessCompression",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("Quality",0,70,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ReduceImageResolution",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("MaxImageResolution",0,300,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("UseTaggedPDF",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SelectPdfVersion",0,0,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("PDFUACompliance",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ExportNotes",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ViewPDFAfterExport",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ExportBookmarks",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("OpenBookmarkLevels",0,1,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("UseTransitionEffects",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("IsSkipEmptyPages",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ExportPlaceholders",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("IsAddStream",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ExportFormFields",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("FormsType",0,0,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("AllowDuplicateFieldNames",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("HideViewerToolbar",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("HideViewerMenubar",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("HideViewerWindowControls",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ResizeWindowToInitialPage",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("CenterWindow",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("OpenInFullScreenMode",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("DisplayPDFDocumentTitle",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("InitialView",0,1,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("Magnification",0,0,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("Zoom",0,100,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("PageLayout",0,0,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("FirstPageOnLeft",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("InitialPage",0,1,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("Printing",0,2,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("Changes",0,4,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("EnableCopyingOfContent",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("EnableTextAccessForAccessibilityTools",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ExportLinksRelativeFsys",0,true,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("PDFViewSelection",0,0,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ConvertOOoTargetToPDFTarget",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("ExportBookmarksToPDFDestination",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignPDF",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("_OkButtonString",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("Watermark",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("EncryptFile",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("PreparedPasswords",0,,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("RestrictPermissions",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("PreparedPermissionPassword",0,Array(),com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignatureLocation",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignatureReason",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignatureContactInfo",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignaturePassword",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignatureCertificate",0,,com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("SignatureTSA",0,"",com.sun.star.beans.PropertyState.DIRECT_VALUE),_ Array("UseReferenceXObject",0,false,com.sun.star.beans.PropertyState.DIRECT_VALUE)) REM open the writer file strPath = ConvertToUrl("/home/wrg/Downloads/example.odt") objWriterDoc = StarDesktop.loadComponentFromURL(strPath, "default", 0, args()) REM open the calc list strPath = ConvertToUrl("/home/wrg/Downloads/example_list.ods") objCalcDoc = StarDesktop.loadComponentFromURL(strPath, "default", 0, args()) objCalcSheet = objCalcDoc.Sheets(0) REM select the cols of all the needed rows PTListRanage = objCalcSheet.getCellRangeByName("A1:B10") REM set watermark params Watermarkargs(0).Name = "Text" Watermarkargs(0).Value = "Init" ' Will change this to custom text based on the calc file ' Watermarkargs(1).Name = "Font" Watermarkargs(1).Value = "Malgun Gothic Semilight" Watermarkargs(2).Name = "Angle" Watermarkargs(2).Value = 315 ' Degrees, int ' Watermarkargs(3).Name = "Transparency" Watermarkargs(3).Value = 88 ' Percent, int ' Watermarkargs(4).Name = "Color" Watermarkargs(4).Value = 12632256 ' FF0000 = Red; number only ' document = objWriterDoc.CurrentController.Frame oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper") REM main loop of dataset lngRows = PTListRanage.Rows.Count - 1 For r = 0 To lngRows objCalcCellForID = objCalcSheet.getCellByPosition(0,r) objCalcCellForName = objCalcSheet.getCellByPosition(1,r) REM process the row if there is a name to process If objCalcCellForName.String <> "" Then REM set the WhoFor text field if objWriterDoc.getTextFieldMasters.hasByName("com.sun.star.text.fieldmaster.SetExpression.WhoFor") then oVar = objWriterDoc.getTextFieldMasters.getByName("com.sun.star.text.fieldmaster.SetExpression.WhoFor") oVar.DependentTextFields(0).content = objCalcCellForName.String else msgbox "WhoFor not found" end if REM set the WhoForID text field if objWriterDoc.getTextFieldMasters.hasByName("com.sun.star.text.fieldmaster.SetExpression.WhoForID") then oVar = objWriterDoc.getTextFieldMasters.getByName("com.sun.star.text.fieldmaster.SetExpression.WhoForID") oVar.DependentTextFields(0).content = objCalcCellForID.String else msgbox "WhoForID not found" end if REM add text watermark Watermarkargs(0).Value = "For ID "+objCalcCellForID.String ' Which text will be shown as the watermark ' oDispHelper.executeDispatch(document, ".uno:Watermark", "", 0, Watermarkargs()) REM export to PDF format strPath = ConvertToURL("/home/wrg/Downloads/example("+objCalcCellForID.String+").pdf") objWriterDoc.storeToURL(strPath, PDFargs()) End If Next r REM close all the files we opened objCalcDoc.close(True) objWriterDoc.close(True) Links to example PDFs, manually made with working links and script made links don't work. Also, here is a zip that includes PDFs, writer file, calc file, and bas file.
VB ListBox list ftp directories and remove multiple lines based on number in folder name
I do get a lot of help from this website searching for a solution but at this point I'm completely stuck. I'm not a programmer, still was able to get that far. The idea of my little project is to download newest version of a program (folder) from FTP server. Unzip files and update current program folder with new files. But before that backup the exiting program folder to a different FTP address. What I'm struggling with is a way they post program versions (folders) on FTP: folder structure on FTP I can't really predict what would be the next folder to download because e.g. for program version: 7.6.16 it might be: WERSJA_NOWY_TEMPLATE_7.6.17 or WERSJA_NOWY_TEMPLATE_7.7.01 what ever is being released. There is an ini file on C drive that holds the current program version. I was able to retrieve that information by reading the line, removing the unnecessary characters and splitting the string: Dim wersja1 As String = File.ReadAllLines("C:\Windows\file.ini").FirstOrDefault(Function(x) x.Contains("WERSJA=")) Dim characterToRemove1 As String = "WERSJA=" Dim wersja2 As String = Replace(wersja1, characterToRemove1, "") Dim characterToRemove2 As String = "T" Dim wersja3 As String = Replace(wersja2, characterToRemove2, "") Dim wersja4 As String() = wersja3.Split(New Char() {"."c}) Dim w1 As String = wersja4(0) Dim w2 As String = wersja4(1) Dim w3 As String = wersja4(2) e.g. from a line: WERSJA=7.6.5T I get: w1 = 7 w2 = 6 w3 = 5 Then I change the last one (w3) to a two digits number (because of the way folders are named on FTP): If w3 < 10 Then w3 = "0" & w3 Else w3 = w3 End If So if: w3 = 5 >> I get 05 w3 = 16 >> I get 16 So far, so good. In the next step I would like to see a filtered list of program versions (folders) in a ListBox or 2 ListBoxes. I would like to filter the list to see only folder with a bigger number than the current program version, so I can choose the correct one to download. Why this way? Because if current version is e.g. 7.6.16 and there are 3 new ones e.g.: 7.6.17 7.6.18 7.7.01 I need to download all of them one by one, update program files and start the program to update sql database in order they were released. I can't skip any version on update. Dim FTPurl As String = "ftp://xx.xx.xxx.xxx/wersje/" Dim FTPwersja As String = "WERSJA_NOWY_TEMPLATE_*" Dim FTPlog As String = "xxx" Dim FTPpass As String = "yyy" Dim clsRequest As FtpWebRequest = System.Net.WebRequest.Create(FTPurl & FTPwersja) clsRequest.Credentials = New System.Net.NetworkCredential(FTPlog, FTPpass) clsRequest.Method = System.Net.WebRequestMethods.Ftp.ListDirectory Dim listResponse As FtpWebResponse = clsRequest.GetResponse Dim reader As StreamReader = New StreamReader(listResponse.GetResponseStream()) 'folder list While reader.Peek >= 0 ListBox1.Items.Add(reader.ReadLine) End While 'remove empty lines For i As Integer = ListBox1.Items.Count - 1 To 0 Step -1 If ListBox1.GetItemText(ListBox1.Items(i)) = String.Empty Then ListBox1.Items.RemoveAt(i) End If Next i The above code gives me this result. I found this code that enables filtering of ListBox but I have no clue on how to convert it to an loop so I would see only folders with bigger numbers than the current version of program: 'filter result in list box Dim items = From it In ListBox1.Items.Cast(Of Object)() Where it.ToString().IndexOf("7.5", StringComparison.CurrentCultureIgnoreCase) >= 0 Dim matchingItemList As List(Of Object) = items.ToList() ListBox1.BeginUpdate() 'ListBox1.Items.Clear() 'add to list For Each item In matchingItemList ListBox1.Items.Remove(item) 'remove from list 'ListBox1.Items.Add(item) 'add to list Next ListBox1.EndUpdate() I also have this code to catch choice and prevent crash when clicked on empty line : Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) _ Handles ListBox1.SelectedIndexChanged Try Dim LB1choice = ListBox1.SelectedItem.ToString() Label5.Text = LB1choice Catch ex As Exception ListBox1.SelectedIndex = 0 End Try End Sub The ideal would be 2 ComboBoxes where 1st would display e.g. WERSJA_NOWY_TEMPLATE_7.6 WERSJA_NOWY_TEMPLATE_7.7 and based on the choice 2nd ComboBox would list newer subfolders in it e.g. WERSJA_NOWY_TEMPLATE_7.6.16 WERSJA_NOWY_TEMPLATE_7.6.17 for the 1st one, and: WERSJA_NOWY_TEMPLATE_7.7.01 for the 2nd one. I much appreciate if anyone could help me this because it's beyond my skills.
Select text between key words
This is a follow on question to Select block of text and merge into new document I have a SGM document with comments added and comments in my sgm file. I need to extract the strings in between the start/stop comments so I can put them in a temporary file for modification. Right now it's selecting everything including the start/stop comments and data outside of the start/stop comments. Dim DirFolder As String = txtDirectory.Text Dim Directory As New IO.DirectoryInfo(DirFolder) Dim allFiles As IO.FileInfo() = Directory.GetFiles("*.sgm") Dim singleFile As IO.FileInfo Dim Prefix As String Dim newMasterFilePath As String Dim masterFileName As String Dim newMasterFileName As String Dim startMark As String = "<!--#start#-->" Dim stopMark As String = "<!--#stop#-->" searchDir = txtDirectory.Text Prefix = txtBxUnique.Text For Each singleFile In allFiles If File.Exists(singleFile.FullName) Then Dim fileName = singleFile.FullName Debug.Print("file name : " & fileName) ' A backup first Dim backup As String = fileName & ".bak" File.Copy(fileName, backup, True) ' Load lines from the source file in memory Dim lines() As String = File.ReadAllLines(backup) ' Now re-create the source file and start writing lines inside a block ' Evaluate all the lines in the file. ' Set insideBlock to false Dim insideBlock As Boolean = False Using sw As StreamWriter = File.CreateText(backup) For Each line As String In lines If line = startMark Then ' start writing at the line below insideBlock = True ' Evaluate if the next line is <!Stop> ElseIf line = stopMark Then ' Stop writing insideBlock = False ElseIf insideBlock = True Then ' Write the current line in the block sw.WriteLine(line) End If Next End Using End If Next This is the example text to test on. <chapter id="Chapter_Overview"> <?Pub Lcl _divid="500" _parentid="0"> <title>Learning how to gather data</title> <!--#start#--> <section> <title>ALTERNATE MISSION EQUIPMENT</title> <para0 verdate="18 Jan 2019" verstatus="ver"> <title> <applicabil applicref="xxx"> </applicabil>Three-Button Trackball Mouse</title> <para>This is the example to grab all text between start and stop comments. </para></para0> </section> <!--#stop#--> Things to note: the start and stop comments ALWAYS fall on a new line, a document can have multiple start/stop sections I thought maybe using a regex on this (<section>[\w+\w]+.*?<\/section>)\R(<\?Pub _gtinsert.*>\R<pgbrk pgnum.*?>\R<\?Pub /_gtinsert>)* Or maybe use IndexOf and LastIndexOf, but I couldn't get that working.
You can read the entire file and split it into an array using the string array of {"<!--#start#-->", "<!--#stop#-->"} to split, into this Element 0: Text before "<!--#start#-->" Element 1: Text between "<!--#start#-->" and "<!--#stop#-->" Element 2: Text after "<!--#stop#-->" and take element 1. Then write it to your backup. Dim text = File.ReadAllText(backup).Split({startMark, stopMark}, StringSplitOptions.RemoveEmptyEntries)(1) Using sw As StreamWriter = File.CreateText(backup) sw.Write(text) End Using Edit to address comment I did make the original code a little compact. It can be expanded out into the following, which allows you to add some validation Dim text = File.ReadAllText(backup) Dim split = text.Split({startMark, stopMark}, StringSplitOptions.RemoveEmptyEntries) If split.Count() <> 3 Then Throw New Exception("File didn't contain one or more delimiters.") text = split(1) Using sw As StreamWriter = File.CreateText(backup) sw.Write(text) End Using
Is it possible to rename the files after copying from source folder?
I copy some test images from source folder.. but i want to make their image name become "001,002" .. and so on. For Each path As ListViewItem In listbat1.Items For Each Ftif As String In Directory.GetFiles(path.SubItems(0).Text, "*.tif") 'For n As Integer = 0 To listbat1.Items.Count - 1 Dim Finfo As New FileInfo(Ftif) My.Computer.FileSystem.CopyFile(Ftif, txtdirectory.Text & imgdir & Finfo.Name & ".tif") 'Next Next Next Is it possible ? if so, can you help me? pls ..
If you want to rename your file using a progressive counter, then you could easily do it using the ToString with a formatting expression. In this example D3 means convert the input number to a string using three numbers and padding with zero if the number is not converted to enough character. Dim counter as Integer = 0 For Each path As ListViewItem In listbat1.Items For Each Ftif As String In Directory.GetFiles(path.SubItems(0).Text, "*.tif") Dim Finfo As New FileInfo(Ftif) Dim destFile = Path.Combine(txtDirectory.Text, imgdir, counter.ToString("D3") + ".tif") My.Computer.FileSystem.CopyFile(Ftif, destFile) Counter = Counter + 1 Next Next Notice also that building a path should always be done using the Path class
replacing inner text of an invalid xml file
I want to replace inner text of the tag of an XML file. The XML file I have is not well formed so we cannot use LINQ-TO-XML. Is there another way to accomplish this? <conf-start ISO-8601-date="2011-05-31"><day>31</day><month>Jan</month><year>2011</year></conf-start> Within the XML file I just want to replace Jan to 01. Note : The month name can change in different files and also the ISO-8601-date="2011-05-31" Can change. So basically is it possible to find the expression to replace the above line in an invalid XML file. i tried this, Dim filePath As String = TextBox1.Text Dim directory1 As String = Path.GetDirectoryName(filePath) Dim split As String() = filePath.Split("\") Dim parentFolder As String = split(split.Length - 2) Dim yourXml = XDocument.Load(TextBox1.Text & "\" & parentFolder & ".xml").Root ' Change each monthname to the number of the month For Each elem In yourXml...<conf-start>.<day>.<month> elem.Value = DateTime.ParseExact(elem.Value, "MMMM", System.Globalization.CultureInfo.InvariantCulture).Month Next ' save file yourXml.Save(TextBox1.Text & "\" & parentFolder & ".xml") but in some files i get errors such as xlink is an undeclared prefix and in some other files i get different errors
Try This Dim y = "<conf-start iso-8601-date=""2011-05-31""><day>31</day><month>Jan</month><year>2011</year></conf-start>" Dim Match = Regex.Match(y, "<month>([^>]*)<\/month>").Groups(1).ToString Regex.Replace(y, Match, DateTime.ParseExact(Match, "MMM", CultureInfo.CurrentCulture).Month.ToString) It will give you OP Like <conf-start iso-8601-date="2011-05-31"><day>31</day><month>01</month><year>2011</year></conf-start>
try this code : Dim ds As New DataSet ds.ReadXml("yourXmlFile.xml") If Not ds Is Nothing Then ds.Tables("conf-start").Rows(0)("month") = DateTime.ParseExact(ds.Tables(0).Rows(0)("month"), "MMM", CultureInfo.CurrentCulture).Month.ToString ds.WriteXml("yourXmlFile.xml") End If