Search code examples
c#xmlxml-namespacesinfopathxmltextwriter

set multiple namespaces with XmlTextWriter


I'm trying to create an infopath form XML file. I was initially following this example programmatically-create-infopath-form-console-app but I'm getting issues with multiple namespaces.

Here's some namespaces in my infopath form XML file

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" 
xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types"

For the most part, when I'm following the example, everything is going well until I read the people picker portion of the XML File.

What I want:

<my:Updated_By>
    <pc:Person>
        <pc:DisplayName></pc:DisplayName>
        <pc:AccountId></pc:AccountId>
        <pc:AccountType></pc:AccountType>
    </pc:Person>
</my:Updated_By>

What I did (1):

        string myNamespace = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2007-09-02T01:11:44";
        ...
        writer.WriteStartElement("my", "myFields", myNamespace);
        writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
        writer.WriteAttributeString("xmlns", "pc", null, "http://schemas.microsoft.com/office/infopath/2007/PartnerControls");

        ...

        writer.WriteStartElement("my", "Updated_By", myNamespace);
        writer.WriteStartElement("pc", "Person");
        writer.WriteEndElement();
        writer.WriteStartElement("pc", "DisplayName");
        writer.WriteEndElement();
        writer.WriteStartElement("pc", "AccountId");
        writer.WriteEndElement();
        writer.WriteStartElement("pc", "AccountType");
        writer.WriteEndElement();
        writer.WriteEndElement();
        ...

What I got (1):

<my:Updated_By>
    <pc xmlns="Person" />
    <pc xmlns="DisplayName" />
    <pc xmlns="AccountId" />
    <pc xmlns="AccountType" />
</my:Updated_By>

I'm not sure if the "xmlns=" makes any difference in the XML file but I would prefer for it to look as close as possible to the XML File produced by infopath

What is the correct way to go about this?


Solution

  • I would use Xml Linq. See code below :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string header = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                                "<my:Updated_By xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
                                  " xmlns:pc=\"http://schemas.microsoft.com/office/infopath/2007/PartnerControls\"" +
                                  " xmlns:dms=\"http://schemas.microsoft.com/office/2009/documentManagement/types\"" +
                                  " xmlns:my=\"http://schemas.microsoft.com/office/infopath/2003/myXSD/2007-09-02T01:11:44\">" +
                                "</my:Updated_By>";
                XDocument doc = XDocument.Parse(header);
                XElement root = doc.Root;
                XNamespace pcNs = root.GetNamespaceOfPrefix("pc");
    
                string name = "John";
                string id = "123";
                string type = "person";
    
                root.Add(new XElement(pcNs + "Person",
                    new XElement(pcNs + "DisplayName", name),
                    new XElement(pcNs + "AccountId", id),
                    new XElement(pcNs + "AccountType", type)
                    ));
    
                doc.Save("filename");
    
            }
        }
    }