Search code examples
c#xmllinq

Insert prefix in a Xml string


I need to be able to write this Xml string:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" 
            xmlns:a="http://www.w3.org/2005/08/addressing" 
            xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" 
            xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

To do this I use this code:

XNamespace myns = "s";

XDocument oXml = new XDocument(new XDeclaration("1.0", "UTF-8", ""));

XElement oRoot = new XElement("Envelope",
    new XAttribute(XNamespace.Xmlns + "s", "http://schemas.xmlsoap.org/soap/envelope/"),
    new XAttribute(XNamespace.Xmlns + "a", "http://www.w3.org/2005/08/addressing"),
    new XAttribute(XNamespace.Xmlns + "fse", "http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/"),
    new XAttribute(XNamespace.Xmlns + "u", "http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")
);


oXml.Add(oRoot);

This is the result, which is fine but the initial s: is missing before Envelope and I don't know how to insert it.

<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" 
          xmlns:a="http://www.w3.org/2005/08/addressing" 
          xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" 
          xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" />

I tried putting an XNamespace at the beginning of the XElement, like this:

XElement oRoot = new XElement(myns + "Envelope",
    new XAttribute(XNamespace.Xmlns + "s", "http://schemas.xmlsoap.org/soap/envelope/"),
    new XAttribute(XNamespace.Xmlns + "a", "http://www.w3.org/2005/08/addressing"),
    new XAttribute(XNamespace.Xmlns + "fse", "http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/"),
    new XAttribute(XNamespace.Xmlns + "u", "http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")
);

But the result is this:

<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" 
          xmlns:a="http://www.w3.org/2005/08/addressing" 
          xmlns:fse="http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/" 
          xmlns:u="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
          xmlns="s" />

I don't know what else to try, can you help me?

EDIT: As I wrote in the question I have already tried to insert the namespace before Envelope, as suggested in the post but it doesn't work for me.


Solution

  • Namespace prefixes only carry meaning within their own scope and can be arbitrarily selected. Stop trying to manually control these and the XML that's output should be correct. That is, both of these elements are the same:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
    <foo:Envelope xmlns:foo="http://schemas.xmlsoap.org/soap/envelope/" />
    

    So just declare the actual namespaces you want to work with in your code and let the XDocument etc insert the required namespace attributes as required:

    XNamespace SchemaNs = "http://schemas.xmlsoap.org/soap/envelope/";
    XNamespace AddressingNs = "http://www.w3.org/2005/08/addressing";
    XNamespace PddNs = "http://www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/FSE/";
    XNamespace OasisNs = "http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
    
    XDocument oXml = new XDocument(new XDeclaration("1.0", "UTF-8", ""));
    
    XElement oRoot = new XElement(SchemaNs + "Envelope");
    
    //Use other namespace objects as appropriate whilst building child elements, etc, as SchemaNs is used above
    
    oXml.Add(oRoot);