Here's my final code in case someone out there can use it...I do have an On Error Resume Next in place because the i9 is a ridiculously picky form and I'm choosing to fill some things in slightly differently than they want me to. I've also chopped out where I'm setting some of my variables in order to keep it shorter. Thanks again to kuujinbo for your help!
Private Sub ExportI9()
Dim pdfTemplate As String = Path.Combine(Application.StartupPath, "PDFs\2017-I9.pdf")
pdfTemplate = Replace(pdfTemplate, "bin\Debug\", "")
Dim fields = New Dictionary(Of String, String)() From {
{"textFieldLastNameGlobal", Me.tbLast.Text},
{"textFieldFirstNameGlobal", Me.tbFirst.Text},
{"textFieldMiddleInitialGlobal", Mid(Me.tbMiddle.Text, 1, 1)},
{"textFieldOtherNames", Me.tbOtherName.Text},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Top/subEmployeeInfo/subSection1Row2/textFieldAddress", addr1},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Top/subEmployeeInfo/subSection1Row2/textFieldAptNum", ""},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Top/subEmployeeInfo/subSection1Row2/textFieldCityOrTown", city1},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Top/subEmployeeInfo/subSection1Row2/State", state1},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Top/subEmployeeInfo/subSection1Row2/textFieldZipCode", zip1},
{"dateFieldBirthDate", Me.dtpBirth.Value},
{"SSN", Me.tbSSN.Text},
{"fieldEmail", ""},
{"fieldPhoneNum", sphone},
{"radioButtonListCitizenship", citizenship},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subCitizenshipStatus/textFieldResidentType", alienuscis},
{"dateAlienAuthDate", dauth},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subAuthorizedAlien/numFormI94Admission", Me.tbi94.Text},
{"numForeignPassport", Me.tbPassport.Text},
{"CountryofIssuance", Me.tbPassportCountry.Text},
{"numAlienOrUSCIS", usc},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subAuthorizedAlien/textFieldResidentType", alienuscis},
{"rbListPerparerOrTranslator", 3},
{"dropdownMultiPreparerOrTranslator", 1},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subPreparerTranslator/subPrepererTranslator1/subTranslatorSignature/subRow2/textFieldFirstName", prepfirst},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subPreparerTranslator/subPrepererTranslator1/subTranslatorSignature/subRow2/textFieldLastName", preplast},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subPreparerTranslator/subPrepererTranslator1/subTranslatorSignature/subRow3/textFieldAddress", Replace(prepadd, "#", "No. ")},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subPreparerTranslator/subPrepererTranslator1/subTranslatorSignature/subRow3/textFieldCityOrTown", prepcity},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subPreparerTranslator/subPrepererTranslator1/subTranslatorSignature/subRow3/State", prepstate},
{"form1/section1Page1/subSection1PositionWrapper/subSection1Bottom/subPreparerTranslator/subPrepererTranslator1/subTranslatorSignature/subRow3/textFieldZipCode", prepzip},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subDocListA1/selectListA1DocumentTitle", doctitle1},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListB/selectListBDocumentTitle", doctitle2},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListC/selectListCDocumentTitle", doctitle3},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subDocListA1/textFieldIssuingAuthority", issued1},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListB/textFieldIssuingAuthority", issued2},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListC/textFieldIssuingAuthority", issued3},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subDocListA1/dateExpiration", expdate1},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListB/dateExpiration", expdate2},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListC/dateExpiration", expdate3},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subDocListA1/textFieldDocumentNumber", docnum1},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListB/textFieldDocumentNumber", docnum2},
{"form1/section2and3Page2/subSection2/subVerificationListsBorder/subListBandCBorder/subDocListC/textFieldDocumentNumber", docnum3},
{"form1/section2and3Page2/subSection2/subCertification/subAttest/dateEmployeesFirstDay", CDate(Me.dtpHired.Value).ToShortDateString},
{"form1/section2and3Page2/subSection2/subCertification/subEmployerInformation/subEmployerInfoRow2/textFieldLastName", certlast},
{"form1/section2and3Page2/subSection2/subCertification/subEmployerInformation/subEmployerInfoRow2/textFieldFirstName", certfirst},
{"form1/section2and3Page2/subSection2/subCertification/subEmployerInformation/subEmployerInfoRow3/textFieldAddress", orgadd},
{"form1/section2and3Page2/subSection2/subCertification/subEmployerInformation/subEmployerInfoRow3/textFieldCityOrTown", orgcity},
{"form1/section2and3Page2/subSection2/subCertification/subEmployerInformation/subEmployerInfoRow3/State", orgstate},
{"form1/section2and3Page2/subSection2/subCertification/subEmployerInformation/subEmployerInfoRow3/textFieldZipCode", orgzip},
{"textBusinessOrgName", orgname}
}
Dim PDFUpdatedFile As String = pdfTemplate
PDFUpdatedFile = Replace(PDFUpdatedFile, "I9", Me.tbSSN.Text & "-I9")
If System.IO.File.Exists(PDFUpdatedFile) Then System.IO.File.Delete(PDFUpdatedFile)
Dim readerPDF As New PdfReader(pdfTemplate)
Dim filledXml = FillXml(fields)
Using ms = New MemoryStream()
Using readerPDF
' I-9 has password security
PdfReader.unethicalreading = True
Dim stamper As New PdfStamper(readerPDF, ms, ControlChars.NullChar, True)
Using stamper
Dim doc As New XmlDocument()
doc.LoadXml(filledXml)
stamper.AcroFields.Xfa.FillXfaForm(doc.DocumentElement)
End Using
End Using
File.WriteAllBytes(PDFUpdatedFile, ms.ToArray())
End Using
End Sub
Public Function FillXml(fields As Dictionary(Of String, String)) As String
' XML_INFILE => physical path to XML file exported from I-9
Dim xmlfile As String
xmlfile = Path.Combine(Application.StartupPath, "PDFs\2017-I9_data.xml")
xmlfile = Replace(xmlfile, "bin\Debug\", "")
Dim kvp As KeyValuePair(Of String, String)
Dim xDoc As XDocument = XDocument.Load(xmlfile)
For Each kvp In fields
' handle multiple elements in I-9 form
Dim elements = xDoc.XPathSelectElements(String.Format("//{0}", kvp.Key))
If elements.Count() > 0 Then
For Each e As XElement In elements
On Error Resume Next
e.Value = kvp.Value
Next
End If
Next
Return xDoc.ToString()
End Function