An InfoPath template have an extension of .XSN which is simply a .CAB file. If you extract it, you will see a set of files. Basically there will be:

  • manifest.xsf
  • myschema.xsd
  • sampledata.xml
  • template.xml and
  • view1.xsl

 

I found a non-straight forward way to create the files if you have some fixed form structure. Here are the actions needed:

File Changes

manifest.xsf

In node: <xsf:xDocumentClass>, you have publishUrl attribute. Make sure you have correct file system path of your destination xsn file.

Eg:

publishUrl="D:\TempWorkArea\infopath_app_template\test\test.xsn"

myschema.xsd

In this file, you have changes in two places.

1. xsd:schema\xsd:element\xsd:complexType\xsd:sequence\

2. xsd:schema\

Make sure you put all the input field details in this file

Eg:

clip_image002

sampledata.xml

Default data file. Optional but good to keep the file.

No changes in this file necessary

template.xml

Entry needed in location m:myFields\

Make sure you put all the input fields in this file.

Eg:

clip_image004

view1.xsl

This file defined the appearance of the form.

In this file you can see <body> tag. Make sure you have sufficient code do handle each input field.

Eg:

clip_image006

The contents of div differs for different controls. Better make a sample infopath form with all needed controls and have a look and implement.

 

Make CAB/XSN

To do this make a definition file with all the above explained files. .ddf is the extension of a definition file. A sample definition file looks like:

;*** Sample Source Code MakeCAB Directive file example

;

.OPTION EXPLICIT ; Generate errors

.Set CabinetNameTemplate=test.xsn

.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory

.Set CompressionType=MSZIP;** All files are compressed in cabinet files

.Set UniqueFiles="OFF"

.Set Cabinet=on

.Set DiskDirectory1=test

manifest.xsf

myschema.xsd

sampledata.xml

template.xml

view1.xsl

;*** <the end>

Note that for CabinetNameTemplate, I put the extension xsn so that you will not need to do a rename task.

Execute the makecab command in command line. Eg:

clip_image002

Source Code

Here is the C# code to do it. I extracted one fresh XSN file and extracted to a folder and renamed with underscore at the beginning.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
 
namespace MakeXSN
{
    public partial class Form1 : Form
    {
        public string templatepath = @"C:\MakeXSN\mytesttemplate\";
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            CreateMenifest();
            CreateXSD();
            CreateTemplete();
            CreateView();
 
            CreateXSN();
        }
 
        private void CreateView()
        {
            string textboxtemplate = @"<div>
          <span class='xdTextBox' hideFocus='1' title='' xd:binding
='my:txtName[NUM]' tabIndex='0' xd:xctname='PlainText' xd:CtrlId='CTRL1' style='WIDTH: 130px'>
						<xsl:value-of select='my:txtName[NUM]'/>
					</span>
				</div>
            ";
 
            string strdata = File.ReadAllText(templatepath + "_view1.xsl");
            StringBuilder sbElements1 = new StringBuilder();
            for (int i = 0; i < numericUpDown1.Value; i++)
            {
                string str = textboxtemplate.Replace("[NUM]", i.ToString());
 
                sbElements1.Append(str + Environment.NewLine);
            }
            strdata = strdata.Replace("[ELEMENTS1]", sbElements1.ToString());
            File.WriteAllText(templatepath + "view1.xsl", strdata);
        }
 
        private void CreateTemplete()
        {
            string strdata = File.ReadAllText(templatepath + "_template.xml");
            StringBuilder sbElements1 = new StringBuilder();
            for (int i = 0; i < numericUpDown1.Value; i++)
            {
                sbElements1.Append("<my:txtName"+i.ToString()+"></my:txtName"+i.ToString()+">" 
		+ Environment.NewLine);
            }
            strdata = strdata.Replace("[ELEMENTS1]", sbElements1.ToString());
            File.WriteAllText(templatepath + "template.xml", strdata);
        }
 
        private void CreateXSD()
        {
            string strdata = File.ReadAllText(templatepath + "_myschema.xsd");
            StringBuilder sbElements1 = new StringBuilder();
            StringBuilder sbElements2 = new StringBuilder();
            for (int i = 0; i < numericUpDown1.Value; i++)
            {
                sbElements1.Append("<xsd:element ref=\"my:txtName"+i.ToString()
		+"\" minOccurs=\"0\"/>" + Environment.NewLine);
                sbElements2.Append("<xsd:element name=\"txtName" + i.ToString() 
		+ "\" type=\"xsd:string\"/>" + Environment.NewLine);
            }
            strdata = strdata
                .Replace("[ELEMENTS1]", sbElements1.ToString())
                .Replace("[ELEMENTS2]", sbElements2.ToString());
            File.WriteAllText(templatepath + "myschema.xsd", strdata);
        }
 
 
 
        private void CreateMenifest()
        {
            string strdata = File.ReadAllText(templatepath + "_manifest.xsf");
            strdata = strdata.Replace("[PUBLISHURL]", templatepath 
		+ @"test\test.xsn");
            File.WriteAllText(templatepath + "manifest.xsf", strdata);
 
        }
        private void CreateXSN()
        {
            Process proc = new Process();
            proc.StartInfo = new ProcessStartInfo("makecab.exe", "/f test.ddf");
            proc.StartInfo.WorkingDirectory = templatepath;
            proc.Start();            
        }
    }
}
VN:F [1.1.6_502]
Rating: 5.0/5 (1 vote cast)
Share:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • DotNetKicks
  • LinkedIn
  • Live
  • MySpace
  • StumbleUpon
  • Technorati

Related posts:

  1. MD5 encryption with c#
  2. How to add columns dynamically on a GridView?
  3. Find your lucky number in c#
  4. Move a control with mouse on form
  5. Get currently logged in user from a service running under LocalSystem account