'''' This code is part of Document Solutions for Word demos.'' Copyright (c) MESCIUS inc. All rights reserved.''ImportsSystem.Collections.GenericImportsSystem.LinqImportsSystem.XmlImportsGrapeCity.Documents.Word '' This example demonstrates how to create a document with multiple ContentControls,'' whose values are mapped to user-created CustomXmlPart file, standart Xml file'' which defines various elements And attributes.'' This document also contain a header And a footer with elements that are also mapped to'' proper xml elements.PublicClassCustomXmlPartsFunctionCreateDocx() AsGcWordDocumentDim doc = NewGcWordDocument() '' Create custom xml part And keep it in the documentCreateOrderCustomXmlFromString(doc) '' Set custom xml document element valueSetDeliveryOption(doc, True) '' Compose document with Case properties bound to proper CustomControls '' Create And map To text fieldCreateOficialBody(doc) '' Create And map Appeal checkbox And AppealDeadline Text controlCreateDeliveryCheckbox(doc) '' Create Header And map Department xml elementCreateHeaderWithMappedDepartment(doc) '' Create Header And map document built-in Author xml elementCreateFooterWithMappedAuthor(doc) '' DoneReturn docEndFunction '' Retrieve a CustomXmlPart from a document by namePrivateSharedFunctionGetCustomXmlPartByName(ByRef doc AsGcWordDocument, ByRef name AsString) AsCustomXmlPartForEach xmlPart In doc.CustomXmlPartsIfString.Compare(xmlPart.XmlDocument.DocumentElement.Name, name, True) = 0ThenReturn xmlPartEndIfNextThrowNew ArgumentException(String.Format("Could not find custom xml part {0}", name))EndFunction '' Find 'Order' CustomXmlPart and set its DeliveryAppeal xml element to value provided by method parameter:PrivateSharedSubSetDeliveryOption(ByRef doc AsGcWordDocument, ByVal deliveryRequired AsBoolean)Dim xmlPart = GetCustomXmlPartByName(doc, "Order") Dim node = xmlPart.XmlDocument.SelectSingleNode("//*[local-name()='Delivery']")If deliveryRequired Then node.InnerText = "true"Else node.InnerText = "false"EndIfEndSub '' Compose half of document body, map "To" text custom control to proper CustomXml fieldPrivateSharedSubCreateOficialBody(ByRef doc AsGcWordDocument)Dim p = doc.Body.Paragraphs.Add("Dear ")Dim tto = p.GetRange().ContentControls.Add(ContentControlType.Text, False) tto.XmlMapping.SetMapping("//grapecity:To", "xmlns:grapecity='http://grapecity.com'") p.GetRange().Runs.First.Font.Size = 10 tto.Font.Size = 10 p.GetRange().Runs.Add(",") doc.Body.Paragraphs.Add() p = doc.Body.Paragraphs.Add("The first shipment of equipment from AMA Ltd has arrived. " +"We are delighted with every piece. Therefore, we decided to make " +"our initial purchase larger than anticipated. I am attaching our " +"purchase order No. 8393 for additional goods. Since you already have " +"a copy of our Procurement Guidelines, I shall not attach them to " +"this order. Current Shipping date is ") '' Add shipping Date control, bound to proper section of Order CustomXmlPart:Dim dateControl = p.GetRange().ContentControls.Add(ContentControlType.Date, False) dateControl.DateFormat = "dd.MM.yyyy"''here we demonstrate how to map CustomControl with namespaces usage, it allows us write''clean And straight XmlPath. Its the right way of XMlMapping dateControl.XmlMapping.SetMapping("//grapecity:Delivery/@DeliveryDate","xmlns:grapecity='http://grapecity.com'") p.GetRange().Paragraphs.Add("If you want to change it, select checkbox below and change Date, " +"then send this letter back to me") dateControl.Font.Italic = True p.GetRange().Runs.First.Font.Size = 12 p.GetRange().Runs.First.Font.Italic = TrueEndSub '' Create footer And map Author built-in property to Text content controlPrivateSharedSubCreateFooterWithMappedAuthor(ByRef doc AsGcWordDocument)Dim footer = doc.Body.Sections.First.Footers(HeaderFooterType.Primary)Dim p = footer.Body.Paragraphs.Add("Sincerely yours, ") If p.Document.Settings.BuiltinProperties.AuthorIsNothingThen p.Document.Settings.BuiltinProperties.Author = "Nancy Davolio"EndIf '' Create Text ContentControl And bind its value to builtin Author property:Dim authorTextControl = p.GetRange().ContentControls.Add(ContentControlType.Text, False) '' Use specialized SetMapping overload for document BuiltInProperties.'' here we bind (map) ContentControl to builtin Author property: authorTextControl.XmlMapping.SetMapping(Function() p.Document.Settings.BuiltinProperties.Author)EndSub '' Create header with Text ContentControl mapped to 'Department' node of 'Order' CustomXml:PrivateSharedSubCreateHeaderWithMappedDepartment(ByRef doc AsGcWordDocument)'' Create Header And fill it with data:Dim header = doc.Body.Sections.First.Headers(HeaderFooterType.Primary)Dim p = header.Body.Paragraphs.Add()Dim departmentTextControl = p.GetRange().ContentControls.Add(ContentControlType.Text, False) '' Get our Case CustomXmlPart:Dim xmlPart = GetCustomXmlPartByName(doc, "Order") Dim departmentNode = xmlPart.XmlDocument.SelectSingleNode("//*[local-name()='Department']")'' Mapping directly to XmlNode: departmentTextControl.XmlMapping.SetMapping(departmentNode)EndSub '' Create Delivery part, Checkbox custom control bound to Delivery node And Date custom control'' bound to details of (possible) Delivery date.PrivateSharedSubCreateDeliveryCheckbox(ByRef doc AsGcWordDocument)Dim p = doc.Body.Paragraphs.Add() '' Create checkbox And map it to Shipping node of 'Case' CustomXmlPart:Dim checkBox = p.GetRange().ContentControls.Add(ContentControlType.CheckBox, False) '' Here we demonstrate how to map CustomControl ignoring namespaces used in the xml.'' This way should be avoided as much as possible as pretty inefficient: checkBox.XmlMapping.SetMapping("//*[local-name()='Delivery']") p.GetRange().Runs.Add("Delivery should be done before ") '' Add shipping Date control, bound to proper section of Order CustomXmlPart:Dim dateControl = p.GetRange().ContentControls.Add(ContentControlType.Date, False) dateControl.DateFormat = "dd.MM.yyyy"'' Here we demonstrate how to map CustomControl with namespaces usage, it allows us write'' clean And straight XmlPath. Its the right way of XMlMapping: dateControl.XmlMapping.SetMapping("//grapecity:Delivery/@DeliveryDate","xmlns:grapecity='http://grapecity.com'")EndSub '' Create XML from a string (see alternative method below)PrivateSharedSubCreateOrderCustomXmlFromString(ByRef doc AsGcWordDocument)Dim sb = NewSystem.Text.StringBuilder(201)Constns = "'http://grapecity.com'" sb.AppendLine("<Order xmlns=" + ns + ">") sb.AppendLine(" <To>Mark Donahue</To>") sb.AppendLine(" <Department>Shipping department</Department>") sb.AppendLine(" <Delivery DeliveryDate=""12.04.2019"">true</Delivery>") sb.AppendLine("</Order>") Dim xml = NewXmlDocument() xml.LoadXml(sb.ToString())Dim xmlPart = doc.CustomXmlParts.Add(xml, Guid.NewGuid().ToString(), NewString() {ns}, "application/xml")EndSub '' Create XML by adding individual nodes one by one'' (this method Is Not used in this sample, the previous'' alternative Is used instead)PrivateSharedSubCreateOrderCustomXml(ByRef doc AsGcWordDocument)'' add a custom xml part with custom settingsConstns = "http://grapecity.com"Dim xml = NewXmlDocument() xml.AppendChild(xml.CreateXmlDeclaration("1.0", "utf-8", Nothing))Dim root = xml.CreateElement("Order", ns) xml.AppendChild(root) Dim tto = root.AppendChild(xml.CreateElement("To", ns)) tto.InnerText = "Mark Donahue" Dim dep = root.AppendChild(xml.CreateElement("Department", ns)) dep.InnerText = "Shipping department" Dim child = xml.CreateElement("Delivery", ns) child.InnerText = "true" child.SetAttribute("DeliveryDate", "12.04.2019") root.AppendChild(child) Dim xmlPart = doc.CustomXmlParts.Add(xml, Guid.NewGuid().ToString(), NewString() {ns}, "application/xml") '' Sad story: we cannot apply schemas To our custom xml parts.'' Unlike in Office excel (where a schema can be serialized inside a document),'' it seems that Word can work with schema URIs only so we cannot place an xsd inside the document.'' This means that we cannot implement native xml-mapping restrictiong And verifying Like'' xmlPart.Schemas.Add(CreateCelebrationScheme())EndSubEndClass