How to create XmlElement attributes with prefix?
If you've already declared your namespace in the root node, you just need to change the SetAttribute
call to use the unprefixed attribute name. So if your root node defines a namespace like this:
<People xmlns:s='http://niem.gov/niem/structures/2.0'>
You can do this and the attribute will pick up the prefix you've already established:
// no prefix on the first argument - it will be rendered as
// s:id='ID_Person_01'
TempElement.SetAttribute("id", "http://niem.gov/niem/structures/2.0", "ID_Person_01");
If you have not yet declared the namespace (and its prefix), the three-string XmlDocument.CreateAttribute
overload will do it for you:
// Adds the declaration to your root node
var attribute = xmlDocToRef.CreateAttribute("s", "id", "http://niem.gov/niem/structures/2.0");
attribute.InnerText = "ID_Person_01"
TempElement.SetAttributeNode(attribute);
Adding a prefix to an xml node
If you are trying to add namespace to the elements after loading the xml document then it is not possible.
From MSDN:
You cannot add, modify, or delete an
XML namespace definition in an
instance of an XML document after the
document has been loaded into the XML
Document Object Model (XMLDOM) parser.
The XML nodes that are used to
represent data in the XML document are
created when the document is loaded
into the XMLDOM parser. These nodes
are permanently bound to their XML
namespace attributes when they are
created. Therefore, the empty XML
namespace declaration (xmlns = "") is
appended to the child nodes of these
nodes to preserve the default XML
namespace attribute of these nodes.
However you can load the input, read each element and write it to another document (or in-memory) which has the namespace set.
Below is the code that parses the string xml, creates a new xml element along with namespace prefix and namespace.
String xmlWithoutNamespace =
@"<Folio><Node1>Value1</Node1><Node2>Value2</Node2><Node3>Value3</Node3></Folio>";
String prefix ="vs";
String testNamespace = "http://www.testnamespace/vs/";
XmlDocument xmlDocument = new XmlDocument();
XElement folio = XElement.Parse(xmlWithoutNamespace);
XmlElement folioNode = xmlDocument.CreateElement(prefix, folio.Name.LocalName, testNamespace);
var nodes = from node in folio.Elements()
select node;
foreach (XElement item in nodes)
{
var node = xmlDocument.CreateElement(prefix, item.Name.ToString(), testNamespace);
node.InnerText = item.Value;
folioNode.AppendChild(node);
}
xmlDocument.AppendChild(folioNode);
xmlDocument now contains the xml with each node prefixed with vs.
How to add multiple different prefixed attributes in XmlDocument
Got answer on my own.
var fourthAttribute = objXMLDocument.CreateAttribute("xsi", "schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
fourthAttribute.InnerText = "xyz.....";
nodeDeclaration.Attributes.Append(objAttribute);
This is how it should be
Is it possible to create an XmlElement with two xml namespaces?
You can do this as follows:
var fooNs = "http://www.example.com/xmlns/foo-version1";
var defNs = "http://www.example.com/xmlns";
var doc = new XmlDocument();
// Create and add the root element
var root = doc.CreateElement("foo", "document", fooNs);
doc.AppendChild(root);
// Add the default namespace (do note the root element is not in this namespace)
var defAttr = doc.CreateAttribute("xmlns");
defAttr.Value = defNs;
root.Attributes.Append(defAttr);
// Create the <foo:bar> element
var bar = doc.CreateElement("foo", "bar", fooNs);
var bazAttr = doc.CreateAttribute("foo", "baz", fooNs);
bazAttr.Value = XmlConvert.ToString(true);
bar.Attributes.Append(bazAttr);
// Add it to the root
root.AppendChild(bar);
Notes:
When creating
XmlElement
andXmlAttribute
nodes in a namespace, always prefer to use theCreate()
overloads that take a prefix, a localName and a namespaceURI:XmlDocument.CreateElement(String, String, String)
XmlDocument.CreateAttribute(String, String, String)
From a semantic point of view, what really matters is the node local name and namespace; the prefix is just a lookup to find a namespace declaration in scope.Notice I didn't explicitly add the
xmlns:foo="http://www.example.com/xmlns/foo-version1"
attribute? It is unnecessary to do this since the root element was created using the required namespace and prefix viadoc.CreateElement("foo", "document", fooNs)
. The framework (XmlWriter
) will automatically emit thexmlns:foo
attribute as it writes theXmlDocument
to XML.If for some reason you need to explicitly create the namespace attribute, you can do it as follows:
// The following is redundant as the framework (XmlWriter) will add the necessary
// xmlns:foo attribute as the XmlDocument is being written. If you need to do it anway
// (e.g. to control the order) you can do it as follows.
// (But note that XML attributes are unordered according to the XML specification, for details
// see https://stackoverflow.com/questions/33746224/in-xml-is-the-attribute-order-important)
var xmlnsNs = "http://www.w3.org/2000/xmlns/";
var fooAttr = doc.CreateAttribute("xmlns", "foo", xmlnsNs);
fooAttr.Value = fooNs;
root.Attributes.Append(fooAttr);
Demo fiddle #1 here.
Incidentally, as written in comments, it's much easier to do this with LINQ to XML:
XNamespace fooNs = "http://www.example.com/xmlns/foo-version1";
XNamespace defNs = "http://www.example.com/xmlns";
var root = new XElement(fooNs + "document"
// Add the namespace declarations with your desired prefixes. Be sure to pass them into the constructor.
, new XAttribute("xmlns", defNs.ToString())
, new XAttribute(XNamespace.Xmlns + "foo", fooNs.ToString())
// And add any required content. The content can be passed into the constructor, or added later.
, new XElement(fooNs + "bar", new XAttribute(fooNs + "baz", true)));
Notes:
With LINQ to XML you never need to worry about the namespace prefix of an
XElement
orXAttribute
. Just create them with the correct namespace and local name as encapsulated byXName
. The framework (XmlWriter
) will automatically emit all necessary namespace attributes as it writes.But if you do need to configure namespaces for some reason you can construct appropriate
XAttribute
objects and then pass them into theXElement
constructor.For further reading see How to: Create a Document with Namespaces (C#) (LINQ to XML).
Demo fiddle #2 here.
Create XML element without namespace prefix inside element with namespace prefix
Changing your Root
class like this should do it:
[XmlRoot(ElementName = "root", Namespace = "http://foo.bar")]
public class Root
{
// note empty namespace here
[XmlElement(ElementName = "child", Namespace = "")]
public Child Child { get; set; }
}
Related Topics
Read Big Txt File, Out of Memory Exception
C# - Which Is the Best Alternative to 'Switch on Type'
How to Derive Xml Element Name from an Attribute Value of a Class Using Annotations
Finding Property Differences Between Two C# Objects
How to Simulate a Mouse Click at a Certain Position on the Screen
How Would I Sort a List of Files by Name to Match How Windows Explorer Displays Them
Testing Smtp Server Is Running via C#
How to Change Route to Username After Logged In
Case Insensitive Regex Without Using Regexoptions Enumeration
How to Iterate Through a Datatable
Closures Behaving Differently in for and Foreach Loops
Why I'm Getting Cs1012: "Too Many Characters in Character Literal" and Cs0019
How to Tell Fluent Nhibernate Not to Map a Class Property
Only Primitive Types or Enumeration Types Are Supported in This Context