ngcable
ngcable

Reputation: 33

XmlDocument - The prefix '' cannot be redefined from '' to 'X'

I am doing this:

 var xml = new XmlDocument();
 xml.AppendChild(xml.CreateXmlDeclaration("1.0", Encoding.UTF8.BodyName, "yes"));
 var el = (XmlElement)xml.AppendChild(xml.CreateElement("Document"));           
 el.SetAttribute("xmlns", "urn:iso:std:iso:20022:tech:xsd:" + SepaSchemaUtils.SepaSchemaToString(schema));

Then to get the XML indented I do:

StringBuilder sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings
{
    Indent = true,
    IndentChars = "  ",
    NewLineChars = "\r\n",
    NewLineHandling = NewLineHandling.Replace
};
using (XmlWriter writer = XmlWriter.Create(sb, settings))
{
    doc.Save(writer);
}

I am getting an exception when doc.Save(writer) is executed.

System.Xml.XmlException: The prefix '' cannot be redefined from '' to 'urn:iso:std:iso:20022:tech:xsd:pain.001.001.03' within the same start element tag.

I've already tried everything I could find. Thank you.

Upvotes: 3

Views: 4341

Answers (2)

Anton Shepelev
Anton Shepelev

Reputation: 1011

In addition to Jon Skeet's answer, I will add that I for one feel no need for LINQ in my work with XML (if at all). I manage namespaces with a few simple helper functions. They are part of my XmlDocUtil module, which I cannot share in full and give but a small example:

using System     ;
using System.Xml ;
using System.Text;

static class Test {

/* ------------------------------ XML helpers ------------------------------- */
static XmlDocument XParDoc( XmlNode parent  )
{   XmlDocument pardoc;
    if( parent.OwnerDocument == null ) pardoc = ( XmlDocument )parent;
    else                               pardoc = parent.OwnerDocument;
    return pardoc;
}

static XmlElement XAddTag
(   XmlNode parent,
    string  tag
)
{   return XAddTagNs( parent, tag, parent.NamespaceURI );  }

static XmlElement XAddTagNs( XmlNode parent, string name, string ns )
{   XmlElement elem;
    elem = XParDoc( parent ).CreateElement( name, ns );
    parent.AppendChild( elem );
    return elem;
}

/* ----------------------------- Demonstration ------------------------------ */
static void Main()
{   XmlDocument       doc;
    XmlNode           root, node;

    doc = new XmlDocument();
    // Add a tag with an explicitely specified namespace:
    root = XAddTagNs  ( doc , "root"         , "root/ns/uri"  );
    // Inherit the root namespace:
    node = XAddTag    ( root, "under_root"                    );
    node = XAddTag    ( node, "terminal_1"                    );

    // Add a tag with anoher namespace:
    node = XAddTagNs  ( root, "another"      , "other/ns/uri" );
    // Inherit that other namespace:
    node = XAddTag    ( node, "under_another"                 );

    // Add a tag without a namespace:
    node = XAddTagNs  ( root, "no_ns"        , null           );
    // ...and one under it:
    node = XAddTagNs  ( node, "under_no_ns"  , null           );

    // Print the result to console:
    Console.Write( XmlToStr( doc ) );
}

static string XmlToStr( XmlDocument doc )
{   StringBuilder     sb;
    XmlWriter         xw;
    XmlWriterSettings xw_sets;

    sb      = new StringBuilder();
    xw_sets = new XmlWriterSettings();
    xw_sets.Indent      = true;
    xw_sets.IndentChars = "  ";
    xw  = XmlWriter.Create( sb, xw_sets );
        doc.WriteTo( xw );
    xw.Dispose();
    return sb.ToString();
}

}

The program above prints:

<?xml version="1.0" encoding="utf-16"?>
<root xmlns="root/ns/uri">
  <under_root>
    <terminal_1 />
  </under_root>
  <another xmlns="other/ns/uri">
    <under_another />
  </another>
  <no_ns xmlns="">
    <under_no_ns />
  </no_ns>
</root>

This defines namespaces in a way that saves the qualification of every tag with a namespace prefix: and relies on the natural namespace inheritance to simplify things.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500675

You're trying to create a Document element not in a namespace, but set the default namespace at the same time. I suspect you just want:

String ns = "urn:iso:std:iso:20022:tech:xsd:" + SepaSchemaUtils.SepaSchemaToString(schema);
var xml = new XmlDocument();
xml.AppendChild(xml.CreateXmlDeclaration("1.0", Encoding.UTF8.BodyName, "yes"));
var el = (XmlElement) xml.AppendChild(xml.CreateElement("Document", ns)); 
el.SetAttribute("xmlns", ns);

Alternatively, I'd strongly recommend using LINQ to XML, which makes this and many other tasks much, much simpler.

Upvotes: 8

Related Questions