{"id":350,"date":"2014-03-10T23:38:26","date_gmt":"2014-03-10T17:38:26","guid":{"rendered":"http:\/\/markwheeler.com\/wordpress\/?p=350"},"modified":"2014-03-10T23:38:26","modified_gmt":"2014-03-10T17:38:26","slug":"import-infopath-xml-to-sql-table-with-ssis","status":"publish","type":"post","link":"https:\/\/markwheeler.com\/?p=350","title":{"rendered":"Import InfoPath XML to SQL Table with SSIS"},"content":{"rendered":"<p>Had a request to import InfoPath forms into a SQL table for consolidating reporting purposes. In this scenario the InfoPath form data is stored in the form XML itself.<br \/>\nThe InfoPath form is for tracking project activities and has 6 fields: Project Leader, Week End Date, Accomplishments, Milestones, Risks, Lessons Learned.<\/p>\n<p>There is no easy way to directly import the InfoPath XML with SSIS. The XML is not in a format that the SSIS XML Task can deal with.<\/p>\n<p>In this scenario, my InfoPath XML looks like this:<br \/>\n<code><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;?mso-infoPathSolution solutionVersion=\"1.0.0.61\" productVersion=\"12.0.0\" PIVersion=\"1.0.0.0\" href=\"<\/span><a style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\" href=\"https:\/\/projectserver.usace.army.mil\/PWA\/WARs\/Forms\/template.xsn\">https:\/\/ServerName\/PWA\/WARs\/Forms\/template.xsn<\/a><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\">\" name=\"urn:schemas-microsoft-com:office:infopath:WARs:-myXSD-2011-09-01T15-42-54\" ?&gt;&lt;?mso-application progid=\"InfoPath.Document\" versionProgid=\"InfoPath.Document.2\"?&gt;&lt;my:myFields xmlns:xsi=\"<\/span><a style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\" href=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\">http:\/\/www.w3.org\/2001\/XMLSchema-instance<\/a><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\">\" xmlns:my=\"<\/span><a style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\" href=\"http:\/\/schemas.microsoft.com\/office\/infopath\/2003\/myXSD\/2011-09-01T15:42:54\">http:\/\/schemas.microsoft.com\/office\/infopath\/2003\/myXSD\/2011-09-01T15:42:54<\/a><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\">\" xmlns:xd=\"<\/span><a style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\" href=\"http:\/\/schemas.microsoft.com\/office\/infopath\/2003\">http:\/\/schemas.microsoft.com\/office\/infopath\/2003<\/a><span style=\"font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 1.5em;\">\" xml:lang=\"en-us\"&gt;<\/span><\/code><\/p>\n<p>&lt;my:WeekEndDate&gt;2014-03-07&lt;\/my:WeekEndDate&gt;<br \/>\n&lt;my:Lead&gt;ProjectManager&lt;\/my:Lead&gt;<\/p>\n<p>&lt;my:group5&gt;<\/p>\n<p>&lt;my:RisksConcerns&gt;Risks 2&lt;\/my:RisksConcerns&gt;<\/p>\n<p>&lt;\/my:group5&gt;<\/p>\n<p>&lt;my:group6&gt;<\/p>\n<p>&lt;my:Milestones&gt;Milestones 1&lt;\/my:Milestones&gt;&lt;my:Milestones&gt;Milestones 2&lt;\/my:Milestones&gt;<\/p>\n<p>&lt;\/my:group6&gt;<\/p>\n<p>&lt;my:group7&gt;<\/p>\n<p>&lt;my:LessonsLearned&gt;Lessons 1&lt;\/my:LessonsLearned&gt;<\/p>\n<p>&lt;\/my:group7&gt;<\/p>\n<p>&lt;my:group8&gt;<\/p>\n<p>&lt;my:Accomplishments&gt;Accomplishment 1&lt;\/my:Accomplishments&gt;&lt;my:Accomplishments&gt;Accomplishment 2&lt;\/my:Accomplishments&gt;&lt;my:Accomplishments&gt;&lt;\/my:Accomplishments&gt;<\/p>\n<p>&lt;\/my:group8&gt;<\/p>\n<p>&lt;\/my:myFields&gt;<\/p>\n<p><code><br \/>\n<\/code><br \/>\nI created the following SSIS package to<\/p>\n<p>1. Download all the InfoPath XML files from the Sharepoint Document Library to a folder on my database server. This is covered in previous postings here.<br \/>\n2. The second step is to convert all the XML files into a CSV file.<br \/>\n3. The resulting CSV files are imported into a SQL Table.<\/p>\n<p>Each box is a ForEach Loop Container. You will also want to create a global string variable; in this case FileName.<\/p>\n<p><a href=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-351\" alt=\"WarImportSSIS\" src=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS-300x205.jpg\" width=\"300\" height=\"205\" \/><\/a><br \/>\n<br clear=\"all\" \/><br \/>\nStarting with the conversion process: Create a ForEach Loop Container using the ForEach File Enumerator. Also set a Variable Mapping to your User::FileName.<\/p>\n<p><a href=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-352\" alt=\"WarImportSSIS2\" src=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS2-300x286.jpg\" width=\"300\" height=\"286\" \/><\/a><br \/>\n<br clear=\"all\" \/><br \/>\nDrop a Script Task into this container: Make sure you set the properties on your script to target the .NET Framework 3.5 and add the references shown.<br \/>\n<a href=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-353\" alt=\"WarImportSSIS3\" src=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS3-300x81.jpg\" width=\"300\" height=\"81\" \/><\/a><br clear=\"all\" \/><br \/>\nNow for the magic sauce: Edit the Script and paste the following; making the applicable changes.<br \/>\n<code><\/code><\/p>\n<p>using System;<br \/>\nusing System.Data;<br \/>\nusing System.Collections.Generic;<br \/>\nusing System.Linq;<br \/>\nusing System.Text;<br \/>\nusing System.Xml;<br \/>\nusing System.IO;<br \/>\nusing Microsoft.SqlServer.Dts.Runtime;<br \/>\nusing System.Windows.Forms;<\/p>\n<p>namespace ST_5921bebcfd87468d967d2eef032f0def.csproj<br \/>\n{<br \/>\n[System.AddIn.AddIn(&#8220;ScriptMain&#8221;, Version = &#8220;1.0&#8221;, Publisher = &#8220;&#8221;, Description = &#8220;&#8221;)]<br \/>\npublic partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase<br \/>\n{<\/p>\n<p>#region VSTA generated code<br \/>\nenum ScriptResults<br \/>\n{<br \/>\nSuccess = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,<br \/>\nFailure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure<br \/>\n};<br \/>\n#endregion<\/p>\n<p>\/*<br \/>\nThe execution engine calls this method when the task executes.<br \/>\nTo access the object model, use the Dts property. Connections, variables, events,<br \/>\nand logging features are available as members of the Dts property as shown in the following examples.<\/p>\n<p>To reference a variable, call Dts.Variables[&#8220;MyCaseSensitiveVariableName&#8221;].Value;<br \/>\nTo post a log entry, call Dts.Log(&#8220;This is my log text&#8221;, 999, null);<br \/>\nTo fire an event, call Dts.Events.FireInformation(99, &#8220;test&#8221;, &#8220;hit the help message&#8221;, &#8220;&#8221;, 0, true);<\/p>\n<p>To use the connections collection use something like the following:<br \/>\nConnectionManager cm = Dts.Connections.Add(&#8220;OLEDB&#8221;);<br \/>\ncm.ConnectionString = &#8220;Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;&#8221;;<\/p>\n<p>Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.<\/p>\n<p>To open Help, press F1.<br \/>\n*\/<\/p>\n<p>public void Main()<br \/>\n{<br \/>\nString XmlInputFile = @&#8221;F:importswars&#8221; + Dts.Variables[&#8220;User::FileName&#8221;].Value;<br \/>\nString XmlOutputFile = @&#8221;F:importswars&#8221; + Dts.Variables[&#8220;User::FileName&#8221;].Value + &#8220;.csv&#8221;;<\/p>\n<p>string keys = &#8220;&#8221;;<br \/>\n\/* We are parsing the XML to a CSV with the following Headers *\/<br \/>\nstring headers = &#8220;&#8221;WeekEndDate&#8221;,&#8221;Lead&#8221;,&#8221;CommentType&#8221;,&#8221;Order&#8221;,&#8221;Comments&#8221;&#8221;;<br \/>\n\/* These are the fields available in our XML *\/<br \/>\nstring[] list1 = new string[2] { &#8220;my:WeekEndDate&#8221;, &#8220;my:Lead&#8221; };<br \/>\nstring[] list2 = new string[5] { &#8220;my:Activities&#8221;, &#8220;my:Accomplishments&#8221;, &#8220;my:Milestones&#8221;, &#8220;my:RisksConcerns&#8221;, &#8220;my:LessonsLearned&#8221; };<\/p>\n<p>StreamWriter sw = new StreamWriter(XmlOutputFile, false);<\/p>\n<p>sw.WriteLine(headers);<\/p>\n<p>for (int i = 0; i &lt; list1.Count(); i++)<br \/>\n{<br \/>\nXmlTextReader reader = new XmlTextReader(XmlInputFile);<\/p>\n<p>while (reader.ReadToFollowing(list1[i]))<br \/>\n{<br \/>\nstring value = reader.ReadString();<br \/>\nkeys = keys + (&#8220;&#8221;&#8221; + value.Replace(&#8220;&#8221;&#8221;,&#8221;&#8216;&#8221;) + &#8220;&#8221;,&#8221;);<br \/>\n}<\/p>\n<p>reader.Close();<br \/>\n}<\/p>\n<p>for (int i = 0; i &lt; list2.Count(); i++)<br \/>\n{<br \/>\nXmlTextReader reader = new XmlTextReader(XmlInputFile);<\/p>\n<p>int j = 0;<br \/>\nwhile (reader.ReadToFollowing(list2[i]))<br \/>\n{<br \/>\nstring value = reader.ReadString();<br \/>\nj++;<br \/>\nsw.WriteLine(keys + &#8220;&#8221;&#8221; + list2[i].Replace(&#8220;my:&#8221;, &#8220;&#8221;) + &#8220;&#8221;,&#8221;&#8221; + j.ToString() + &#8220;&#8221;,&#8221;&#8221; + value.Replace(&#8220;&#8221;&#8221;, &#8220;&#8216;&#8221;) + &#8220;&#8221;&#8221;);<br \/>\n}<\/p>\n<p>reader.Close();<br \/>\n}<\/p>\n<p>sw.Close();<br \/>\n}<\/p>\n<p>}<br \/>\n}<\/p>\n<p>This script opens each XML and streams it to a formatted CSV file.<br \/>\nThe next step is to import these CSV files into your SQL Table.<br \/>\nCreate another ForEach Loop Container; setting your ForEach File Enumerator to *.csv and the global variable mapping.<br \/>\nAdd a Dataflow task. This Dataflow task will contain a Flat File Source linking to an OLE Database Destination.<br \/>\nThe Flat File Source will prompt you to create a Flat File Connection. Use one of your .CSV files to get started.<br \/>\nBut in the property panel of the connection set an Expression for the ConnectionString to use your global filename variable.<\/p>\n<p><a href=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS4.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-354\" alt=\"WarImportSSIS4\" src=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS4-300x116.jpg\" width=\"300\" height=\"116\" \/><\/a><br clear=\"all\" \/><br \/>\nA couple of additional notes: By default, the table creation script in the OLE Database Destination created my WeekEndDate and Comments as varchar(50) datatype.<br \/>\nYou will want to change this if applicable in the Flat File Source Output properties.<\/p>\n<p><a href=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS6.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-356\" alt=\"WarImportSSIS6\" src=\"http:\/\/markwheeler.com\/wordpress\/wp-content\/uploads\/2014\/03\/WarImportSSIS6-300x300.jpg\" width=\"300\" height=\"300\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Had a request to import InfoPath forms into a SQL table for consolidating reporting purposes. In this scenario the InfoPath form data is stored in the form XML itself. The InfoPath form is for tracking project activities and has 6 fields: Project Leader, Week End Date, Accomplishments, Milestones, Risks, Lessons [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[2,11,1],"tags":[58,110],"class_list":["post-350","post","type-post","status-publish","format-standard","hentry","category-computer","category-software","category-uncategorized","tag-infopath","tag-ssis"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/markwheeler.com\/index.php?rest_route=\/wp\/v2\/posts\/350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/markwheeler.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/markwheeler.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/markwheeler.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/markwheeler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=350"}],"version-history":[{"count":0,"href":"https:\/\/markwheeler.com\/index.php?rest_route=\/wp\/v2\/posts\/350\/revisions"}],"wp:attachment":[{"href":"https:\/\/markwheeler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/markwheeler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/markwheeler.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}