Inserting xml nodes containing namespaces outside of document node - c#

I'm creating an XML document in C# that is similar to the following
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>2015-05-17-track.kml</name>
</Document>
</kml>
I can create everything except for the kml node. How do I add this to the XmlDocument?
This is the code I'm using, without the kml node.
doc = new XmlDocument();
XmlElement root = doc.CreateElement("Document");
doc.AppendChild(root);
//form the declaration
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null );
doc.InsertBefore(declaration, root);
XmlNode nameNode = doc.CreateNode(XmlNodeType.Element, "name", "");
nameNode.InnerText = name;
root.AppendChild(nameNode);

Append child to DocumentElement.
XmlNode nameNode = doc.CreateNode(XmlNodeType.Element, "name", "");
nameNode.InnerText = name;
doc.DocumentElement.AppendChild(nameNode );

Turns out I was misled by the 'Document' node. It's been a while and I thought the XmlDocument.DocumentElement always had a tag of 'Document'. Wrong!
Here is the revised code
doc = new XmlDocument();
XmlElement root = doc.CreateElement( "kml" );
root.SetAttribute( "xmlns", "http://www.opengis.net/kml/2.2" );
root.SetAttribute( "xmlns:gx", "http://www.google.com/kml/ext/2.2" );
root.SetAttribute( "xmlns:kml", "http://www.opengis.net/kml/2.2" );
root.SetAttribute( "xmlns:atom", "http://www.w3.org/2005/Atom" );
doc.AppendChild( root );
//form the declaration
XmlDeclaration declaration = doc.CreateXmlDeclaration( "1.0", "UTF-8", null );
doc.InsertBefore( declaration, root );
//Document node
XmlElement documentNode = doc.CreateElement( "Document" );
root.AppendChild( documentNode );
//add the name node
XmlNode nameNode = doc.CreateNode( XmlNodeType.Element, "name", "" );
nameNode.InnerText = name;
documentNode.AppendChild( nameNode );

Related

Convert XMLDocument to XDocument ,getting names spaces Modifing from xsi to p1

i create an XMLDocument:
`
XmlDocument doc = new XmlDocument();
XmlDeclaration declaire = doc.CreateXmlDeclaration("1.0", "utf-8", null);
// -----------------------create root-----------------------------
XmlElement rootnode = doc.CreateElement( "BMECAT");
doc.InsertBefore(declaire, doc.DocumentElement);
doc.AppendChild(rootnode);
//Console.WriteLine(sb.ToString());
//get attribute for BmeCat
rootnode.SetAttribute("version", "2005");
XmlAttribute atr = doc.CreateAttribute("xsi", "schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
atr.Value = "http://www.adlnet.org/xsd/adlcp_v1p3";
rootnode.SetAttributeNode(atr);
rootnode.Attributes.Append(atr);`
then i convert it to XDocument using the function below but i get a NameSpace changed like this
XDocument ToXDocument(XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
`
below the xml and the XDocument
<?xml version="1.0" encoding="utf-8"?>
<BMECAT version="2005" p1:schemaLocation="http://www.adlnet.org/xsd/adlcp_v1p3" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance">
<?xml version="1.0" encoding="utf-8"?>
<BMECAT version="2005" xsi:schemaLocation="http://www.adlnet.org/xsd/adlcp_v1p3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
You need to explicitly add the xsi namespace declaration manually at the beginning of your element.
Nodes are processed in document order and the namespace declaration appears later after it is first used. It doesn't know to use xsi for the prefix until it's too late.
var doc = new XmlDocument();
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
var root = (XmlElement)doc.AppendChild(doc.CreateElement("BMECAT"));
var xsi = "http://www.w3.org/2001/XMLSchema-instance";
root.SetAttribute("xmlns:xsi", xsi); //set the namespace now
root.SetAttribute("schemaLocation", xsi, "http://www.adlnet.org/xsd/adlcp_v1p3");
root.SetAttribute("version", "2005");

'This document already has a 'DocumentElement' node.'

I am trying to create a xml document of following format
<TemplateID>xxxxx</TemplateID>
<CaptionOptions>
<CaptionField>
<Field>xxx</Field>
<Text>xxx</Text>
</CaptionField>
<CaptionField>
<Field>xxxx</Field>
<Text>""</Text>
</CaptionField>
</CaptionOptions>
Here is the code that I wrote
XmlDocument xml2 = new XmlDocument();
XmlElement e = xml2.CreateElement("TemplateID");
e.InnerText = "xxxx";
xml2.AppendChild(e);
XmlElement root2 = xml2.CreateElement("CaptionOptions");
xml2.AppendChild(root2); //error here
XmlElement child2a = xml2.CreateElement("CaptionField");
root2.AppendChild(child2a);
XmlElement child2aa = xml2.CreateElement("Field");
child2a.InnerText = "xxxx";
XmlElement child2ab = xml2.CreateElement("Text");
child2a.InnerText = "xxxx";
child2a.AppendChild(child2aa);
child2a.AppendChild(child2ab);
child2a.AppendChild(child2aa);
child2a.AppendChild(child2ab);
My real code was different from the one I was trying to ask earlier....
You could use
XmlElement child = xml.CreateElement("Players");
child.SetAttribute("Nationality", "England");
child.InnerText = "Rooney";
You need to create attributes and append them to the Player element. But your xml hierarchy doesn't look right.
As discussed, now edited.
XmlDocument doc = new XmlDocument();
XmlElement template = doc.CreateElement("Template");
XmlNode id = doc.CreateElement("TemplateID");
id.InnerText = "123456";
template.AppendChild(id);
doc.AppendChild(template);
XmlElement options = doc.CreateElement("CaptionOptions");
XmlElement captionField = doc.CreateElement("CaptionField");
XmlElement field1 = doc.CreateElement("Field");
field1.InnerText = "Field1Text";
XmlElement text1 = doc.CreateElement("Field");
text1.InnerText = "Text1Text";
captionField.AppendChild(field1);
captionField.AppendChild(text1);
options.AppendChild(captionField);
template.AppendChild(options);
string xml = doc.OuterXml;
Hope that helps.

How to create root node with xmlns:xsi but no prefix?

What's the proper way to create a root node without the prefix, but have it display xmlns:xsi="blah"? Basically I want something like this:
<EDSCrate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="EDS_Crate_2010-02-10.xsd" version="0.95">
<Whatever>
</Whatever>
</EDSCrate>
However, I've tried many ways, it just won't give me a simple node without the namespace, and even if it does, it doesn't give me the proper xmlns:xsi in the attribute.
I'd like to avoid any hack like overriding the ToString and replacing the text myself in the XmlWriter.
string uri = "http://www.w3.org/2001/XMLSchema-instance";
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "UTF-8", null));
nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("xsi", uri);
XmlElement root = doc.CreateElement("EDSCrate", uri);
// at this point, it already added xmlns="http://www.w3.org/2001/XMLSchema-instance" without me doing anything
root.RemoveAllAttributes();
// but i want xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"!!
root.SetAttribute("xmlns:xsi", uri);
root.SetAttribute("xsi:noNamespaceSchemaLocation", "EDS_Crate_2010-02-10.xsd");
string uri = "http://www.w3.org/2001/XMLSchema-instance";
var doc = new XmlDocument();
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "UTF-8", null));
var root = doc.CreateElement("EDSCrate");
doc.AppendChild(root);
root.AppendChild(doc.CreateElement("Whatever"));
var attr = doc.CreateAttribute("xsi", "noNamespaceSchemaLocation", uri);
attr.InnerText = "EDS_Crate_2010-02-10.xsd";
root.SetAttributeNode(attr);
root.SetAttribute("version", "0.95");
I find using Linq2Xml easier.
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
var xdoc = new XDocument(
new XElement(
"EDSCrate",
new XAttribute(XNamespace.Xmlns + "xsi", xsi),
new XAttribute(xsi + "noNamespaceSchemaLocation", "EDS_Crate_2010-02-10.xsd"),
new XAttribute("version", "0.95"),
new XElement("Whatever","")
)
);
var xml = xdoc.ToString();
OUTPUT:
<EDSCrate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="EDS_Crate_2010-02-10.xsd"
version="0.95">
<Whatever></Whatever>
</EDSCrate>

Creating XML document with Two root nodes

I want to create XML with two root nodes, like this
<?xml version="1.0" encoding="IBM437"?>
<header1>
<header2>
<fracc>6004</fracc>
<txncode>HTH</txncode>
<reason>testing</reason>
<timeout>20</timeout>
<rdate>2/3/2015 12:00:00 AM</rdate>
<rtime>6/18/2015 1:20:00 PM</rtime>
<seqno>5</seqno>
<prefix>8</prefix>
<msgtype>trr</msgtype>
<sendto>trr</sendto>
<replyto>trr</replyto>
</header2>
</header1>
My code is like this, I'm unable to add two root elements with my code, it's a must to use XmlDocument class.
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("header" );
xmlDoc.AppendChild(rootNode);
XmlNode accountNode = xmlDoc.CreateElement("fracc");
accountNode.InnerText = Infracc;
rootNode.AppendChild(accountNode);
XmlNode txnNode = xmlDoc.CreateElement("txncode");
txnNode.InnerText = Intxncode;
rootNode.AppendChild(txnNode);
XmlNode reasonNode = xmlDoc.CreateElement("reason");
reasonNode.InnerText = Inreason;
rootNode.AppendChild(reasonNode);
XmlNode timeoutNode = xmlDoc.CreateElement("timeout");
timeoutNode.InnerText = Intimeout.ToString();
rootNode.AppendChild(timeoutNode);
XmlNode rdateNode = xmlDoc.CreateElement("rdate");
rdateNode.InnerText = Indate.ToString();
rootNode.AppendChild(rdateNode);
XmlNode rtimeNode = xmlDoc.CreateElement("rtime");
rtimeNode.InnerText = Intime.ToString();
rootNode.AppendChild(rtimeNode);
XmlNode seqnoNode = xmlDoc.CreateElement("seqno");
seqnoNode.InnerText = Inseqno.ToString();
rootNode.AppendChild(seqnoNode);
XmlNode prefixNode = xmlDoc.CreateElement("prefix");
prefixNode.InnerText = Inprefix.ToString();
rootNode.AppendChild(prefixNode);
XmlNode msgtypeNode = xmlDoc.CreateElement("msgtype");
msgtypeNode.InnerText = Inmsgtype;
rootNode.AppendChild(msgtypeNode);
XmlNode sendtoNode = xmlDoc.CreateElement("sendto");
sendtoNode.InnerText = Insendto;
rootNode.AppendChild(sendtoNode);
XmlNode replytoNode = xmlDoc.CreateElement("replyto");
replytoNode.InnerText = Inreplyto;
rootNode.AppendChild(replytoNode);
xmlDoc.Save("boc.xml");
xmlDoc.Load("boc.xml");
xmlDoc.Save(Console.Out);
return xmlDoc;
and my output is this
<?xml version="1.0" encoding="IBM437"?>
<header>
<fracc>6004</fracc>
<txncode>ttt</txncode>
<reason>testing</reason>
<timeout>20</timeout>
<rdate>2/3/2015 12:00:00 AM</rdate>
<rtime>6/18/2015 1:20:00 PM</rtime>
<seqno>5</seqno>
<prefix>8</prefix>
<msgtype>tt</msgtype>
<sendto>t</sendto>
<replyto>t</replyto>
</header>
Please help me to add two root nodes.
You are not adding 2 root elements.
Change your lines of code
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("header" );
xmlDoc.AppendChild(rootNode);
like below -
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode1 = xmlDoc.CreateElement("header1");
xmlDoc.AppendChild(rootNode1);
XmlNode rootNode = xmlDoc.CreateElement("header2");
rootNode1.AppendChild(rootNode);
Based on your sample output, it's clear that <header1> is the root element and <header2> is inside <header1>, so all you need to do is append <header2> inside <header1> and append the rest of the elements inside <header2>. This code should work
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("header1");
xmlDoc.AppendChild(rootNode);
XmlNode rootNode2 = xmlDoc.CreateElement("header2");
rootNode.AppendChild(rootNode2);
XmlNode accountNode = xmlDoc.CreateElement("fracc");
accountNode.InnerText = Infracc;
rootNode2.AppendChild(accountNode);
XmlNode txnNode = xmlDoc.CreateElement("txncode");
txnNode.InnerText = Intxncode;
rootNode2.AppendChild(txnNode);
XmlNode reasonNode = xmlDoc.CreateElement("reason");
reasonNode.InnerText = Inreason;
rootNode2.AppendChild(reasonNode);
XmlNode timeoutNode = xmlDoc.CreateElement("timeout");
timeoutNode.InnerText = Intimeout.ToString();
rootNode2.AppendChild(timeoutNode);
XmlNode rdateNode = xmlDoc.CreateElement("rdate");
rdateNode.InnerText = Indate.ToString();
rootNode2.AppendChild(rdateNode);
XmlNode rtimeNode = xmlDoc.CreateElement("rtime");
rtimeNode.InnerText = Intime.ToString();
rootNode2.AppendChild(rtimeNode);
XmlNode seqnoNode = xmlDoc.CreateElement("seqno");
seqnoNode.InnerText = Inseqno.ToString();
rootNode2.AppendChild(seqnoNode);
XmlNode prefixNode = xmlDoc.CreateElement("prefix");
prefixNode.InnerText = Inprefix.ToString();
rootNode2.AppendChild(prefixNode);
XmlNode msgtypeNode = xmlDoc.CreateElement("msgtype");
msgtypeNode.InnerText = Inmsgtype;
rootNode2.AppendChild(msgtypeNode);
XmlNode sendtoNode = xmlDoc.CreateElement("sendto");
sendtoNode.InnerText = Insendto;
rootNode2.AppendChild(sendtoNode);
XmlNode replytoNode = xmlDoc.CreateElement("replyto");
replytoNode.InnerText = Inreplyto;
rootNode2.AppendChild(replytoNode);
xmlDoc.Save("boc.xml");
xmlDoc.Load("boc.xml");
xmlDoc.Save(Console.Out);
return xmlDoc;
Working fiddle: https://dotnetfiddle.net/EevsJq

c# write xml muitiable atrrtibutes

I am creating xml file with c#, The xml is:
<?xml version="1.0" encoding="utf-8"?>
<Project Title="old one"
Version="1.5.1.0"
Author=""
EmphasisColor1Label=""
EmphasisColor1="#000000"
EmphasisStyle1="---" >
</Project>
my c# code is:
XmlDocument doc = new XmlDocument();
XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(decl);
XmlElement ChatMapper = doc.CreateElement("Project");
doc.AppendChild(ChatMapper);
XmlNode xmldocSelect = doc.SelectSingleNode("Project");
//Crteate Attribute
XmlAttribute attra = doc.CreateAttribute("Title");
attra.Value ="old one";
xmldocSelect.Attributes.Append(attra);
XmlAttribute attrb = doc.CreateAttribute("Version");
attrb.Value ="1.5.1.0";
xmldocSelect.Attributes.Append(attrb);
XmlAttribute attrc = doc.CreateAttribute("EmphasisColor1Label");
attrc.Value ="";
xmldocSelect.Attributes.Append(attrc);
XmlAttribute attrd = doc.CreateAttribute("EmphasisColor1");
attrd.Value ="#000000";
xmldocSelect.Attributes.Append(attrd);
XmlAttribute attre = doc.CreateAttribute("EmphasisStyle1");
attre.Value ="---";
xmldocSelect.Attributes.Append(attre);
That is not smart and too long, anyone knows how to make it shorter?
You can use System.Xml.Linq namespace to create xml. Code snippet in C#:
XDocument doc = new XDocument(
new XElement("Project ",
new XAttribute("Title", "old one"),
new XAttribute("Version", "1.5.1.0"),
new XAttribute("Author", ""),
new XAttribute("EmphasisColor1Label", ""),
new XAttribute("EmphasisColor1", "#000000"),
new XAttribute("EmphasisStyle1", "")
)
);
doc.Save("Project.xml");
Using LINQ:-
using System.Xml.Linq;
var xml =
new XElement("Project",
new XAttribute("Title", "old one"),
new XAttribute("Version", "1.5.1.0"),
new XAttribute("Author", ""),
new XAttribute("EmphasisColor1Label", ""),
new XAttribute("EmphasisColor1", "#000000"),
new XAttribute("EmphasisStyle1", "---")
);
xml.Save("Project.xml");
WITHOUT LINQ:-
XmlDocument doc = new XmlDocument();
XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(decl);
XmlElement ChatMapper = doc.CreateElement("Project");
ChatMapper.SetAttribute("Title", "old one");
ChatMapper.SetAttribute("Version", "1.5.1.0");
ChatMapper.SetAttribute("EmphasisColor1", "#000000");
ChatMapper.SetAttribute("EmphasisStyle1", "---");
doc.AppendChild(ChatMapper);
doc.Save("project.xml");

Categories