How to generate a XML-file with multiple namespaces in root element with XDocument in C#?

849 views Asked by At

I want to generate a custom manifest.xml file for an Outlook Add-In using XDocument in C#.

My current XML file (what I want to generate now) looks as following:

<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
           xmlns:mailappor="http://schemas.microsoft.com/office/mailappversionoverrides"
           xsi:type="MailApp">
  <Id>{0026EAB0-AFBA-43FE-A3FA-C479B6FEECCA}</Id>
  <Version>2.0.0.0</Version>
  <!-- More elements -->
</OfficeApp>

My main problem is, that I can't manage to add multiple namespaces to the OfficeApp-element.

I already tried the following:

private readonly XNamespace Xsi = "xsi:";
private readonly XNamespace MicrosoftSchemasAppsForOffice = "http://schemas.microsoft.com/office/appforoffice/1.1";
private readonly XNamespace W3 = "http://www.w3.org/2001/XMLSchema-instance";
private readonly XNamespace MicrosoftSchemasOfficeBasicTypes = "http://schemas.microsoft.com/office/officeappbasictypes/1.0";
private readonly XNamespace MicrosoftSchemasMailAppVersion = "http://schemas.microsoft.com/office/mailappversionoverrides";

private XDocument GenerateDocument()
{
    return new XDocument(
      new XDeclaration("1.0", "utf-8", null),
      new XElement("OfficeApp",
        new XAttribute("xmlns", MicrosoftSchemasAppsForOffice),
        new XAttribute(XNamespace.Xmlns + "xsi", W3),
        new XAttribute(XNamespace.Xmlns + "bt", MicrosoftSchemasOfficeBasicTypes),
        new XAttribute(XNamespace.Xmlns + "mailappor", MicrosoftSchemasMailAppVersion),
        new XAttribute(Xsi + "type", "MailApp"),
        new XElement("Id", "{" + Guid.NewGuid().ToString() + "}"),
        new XElement("Version", "2.0.0.0")
      )
    );
}

Which leaded to the following Exception:

System.Xml.XmlException: 'The prefix '' cannot be redefined from '' to    'http://schemas.microsoft.com/office/appforoffice/1.1' within the same start element tag.'

I also tried to replace line

new XAttribute("xmlns", MicrosoftSchemasAppsForOffice),

with

new XAttribute(XNamespace.Xmlns.NamespaceName, MicrosoftSchemasAppsForOffice),

but this gave me the following Exception:

System.Xml.XmlException: 'The ':' character, hexadecimal value 0x3A, cannot be included in a name.'

After hours of trying and failing I still don't know how to handle the xmlns-namespace properly. What am I doing wrong? I think the XML-Code I am trying to generate is valid as it works pretty fine.

I'm thankful for any hint. Thanks!

2

There are 2 answers

0
codernr On BEST ANSWER

Your root namespace doesn't have to be added as attribute, just used as namespace for elements. Also, you have to use xsi namespace value with the type attribute:

private readonly XNamespace MicrosoftSchemasAppsForOffice = "http://schemas.microsoft.com/office/appforoffice/1.1";
private readonly XNamespace W3 = "http://www.w3.org/2001/XMLSchema-instance";
private readonly XNamespace MicrosoftSchemasOfficeBasicTypes = "http://schemas.microsoft.com/office/officeappbasictypes/1.0";
private readonly XNamespace MicrosoftSchemasMailAppVersion = "http://schemas.microsoft.com/office/mailappversionoverrides";

private XDocument GenerateDocument()
{
    return new XDocument(
      new XDeclaration("1.0", "utf-8", null),
      new XElement(MicrosoftSchemasAppsForOffice + "OfficeApp",
        new XAttribute(XNamespace.Xmlns + "xsi", W3),
        new XAttribute(XNamespace.Xmlns + "bt", MicrosoftSchemasOfficeBasicTypes),
        new XAttribute(XNamespace.Xmlns + "mailappor", MicrosoftSchemasMailAppVersion),
        new XAttribute(W3 + "type", "MailApp"),
        new XElement(MicrosoftSchemasAppsForOffice + "Id", "{" + Guid.NewGuid().ToString() + "}"),
        new XElement(MicrosoftSchemasAppsForOffice + "Version", "2.0.0.0")
      )
    );
}
0
jdweng On

Try getting namespace right is hard in XDocument so I normally just parse a string

            string xml = 
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                "<OfficeApp xmlns=\"http://schemas.microsoft.com/office/appforoffice/1.1\"" +
                   " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
                   " xmlns:bt=\"http://schemas.microsoft.com/office/officeappbasictypes/1.0\"" +
                   " xmlns:mailappor=\"http://schemas.microsoft.com/office/mailappversionoverrides\"" +
                   " xsi:type=\"MailApp\">" +
                "</OfficeApp>";

            XDocument doc = XDocument.Parse(xml);
            XElement officeApp = doc.Root;
            XNamespace ns = officeApp.GetDefaultNamespace();
            officeApp.Add(new XElement(ns + "Id","{0026EAB0-AFBA-43FE-A3FA-C479B6FEECCA}"));
            officeApp.Add(new XElement(ns + "Version","2.0.0.0"));