Reputation: 33
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
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
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