Creating XML document with Two root nodes - c#

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

Related

'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.

Reading XML in Asp.net not getting any results

I am using following code to read an XML file from this address.
XmlDocument xdoc = new XmlDocument();
xdoc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
XmlNodeList nodeList = xdoc.DocumentElement.SelectNodes("//gesmes/Cube/Cube");
if (nodeList == null) lblOutput.Text = "node is null";
foreach (XmlNode node in nodeList)
{
XmlNode innerNode = node.SelectSingleNode(".//Cube");
lblOutput.Text = innerNode.Attributes["currency"].Value;
}
The problem is I don't get any thing. nodeList.Count always gives me 0.
You need to handle the namespaces correctly.
There are probably more then one way to handle them and this is one
XmlDocument xdoc = new XmlDocument();
xdoc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
XmlNamespaceManager xnm = new XmlNamespaceManager(xdoc.NameTable);
xnm.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");
xnm.AddNamespace("eurofxref", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
XmlNodeList nodeList = xdoc.DocumentElement.SelectNodes("//gesmes:Envelope/eurofxref:Cube/eurofxref:Cube", xnm);
if (nodeList == null)
{
var text = "node is null";
}
foreach (XmlNode node in nodeList)
{
XmlNode innerNode = node.SelectSingleNode(".//eurofxref:Cube", xnm);
var text = innerNode.Attributes["currency"].Value;
}
I don't know why it has to be this complicated but....
XmlDocument xdoc = new XmlDocument();
xdoc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
XmlNamespaceManager xMan = new XmlNamespaceManager(xdoc.NameTable);
xMan.AddNamespace("def", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
XmlNodeList nodeList = xdoc.DocumentElement.SelectNodes("//def:Cube", xMan);

XmlDocument - SelectSingleNode with namespace

This is my code:
XmlTextReader reader = new XmlTextReader(xmlPath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNode root = xmlDoc.DocumentElement;
XmlNode node = root.SelectSingleNode("marketingid");
XML that works:
<confirmsubmit>
<marketingid>-1</marketingid>
</confirmsubmit>
XML that doesn't work:
<confirmsubmit xmlns="http:....">
<marketingid>-1</marketingid>
</confirmsubmit>
What is the way to deal with the xmlns attribute and how can i parse it?
Is it has anything to do with namespace?
EDIT:
This is the code that works:
XmlTextReader reader = new XmlTextReader(xmlPath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
XmlNode book = xmlDoc.SelectSingleNode("/ns:confirmsubmit/ns:marketingid", nsmgr);
This all XPath is more complicated than seems, I would recommand to begginers like my to read: http://www.w3schools.com/xpath/xpath_syntax.asp
You need to add a XmlNamespaceManager instance in the game, as shown in this example from the documentation:
public class Sample
{
public static void Main()
{
XmlDocument doc = new XmlDocument();
doc.Load("booksort.xml");
//Create an XmlNamespaceManager for resolving namespaces.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bk", "urn:samples");
//Select and display the value of all the ISBN attributes.
XmlNodeList nodeList;
XmlElement root = doc.DocumentElement;
nodeList = root.SelectNodes("/bookstore/book/#bk:ISBN", nsmgr);
foreach (XmlNode isbn in nodeList){
Console.WriteLine(isbn.Value);
}
}
}
Here is how to do it from LINQ to XML. Short and simple
const string xml = #"<confirmsubmit xmlns='http:....'>
<marketingid>-1</marketingid>
</confirmsubmit>";
XElement element = XElement.Parse(xml);
var requestedElement = element.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("marketingid"));
xmlns attribute is used at XHTML and defines namespace for a document. You can parse it like:
XDocument xdoc = XDocument.Load(xmlPath);
var attrib = xdoc.Root.Attribute("xmlns").Value;

xml nodes editing based on an xmlElement

I have tried two ways but they both didnt work..
the first way::
string filepath = Server.MapPath[this is not a link]("XMLFile2.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.Load(filepath);
XmlNode root = xdoc.DocumentElement;
XmlNode idNode = root.SelectSingleNode("/students/student/id");
if (idNode.Value == 9.ToString())
{
var nodeOfStudent = xdoc.SelectNodes("/students/student[#id='9']");
nodeOfStudent[1].InnerXml = TextBox_firstname.Text;
nodeOfStudent[2].InnerXml = TextBox_lastname.Text;
nodeOfStudent[3].InnerXml = TextBox_dob.Text;
nodeOfStudent[4].InnerXml = TextBox_class.Text;
nodeOfStudent[5].InnerXml = TextBox_section.Text;
nodeOfStudent[6].InnerXml = TextBox_telephone.Text;
}
the second way::
string filepath = Server.MapPath("XMLFile2.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.Load(filepath);
XmlNode root = xdoc.DocumentElement;
XmlNode idNode = root.SelectSingleNode("/students/student/id");
xdoc.SelectSingleNode("/students/student[#id='10']/firstname").InnerXml = TextBox_firstname.Text;
xdoc.DocumentElement.AppendChild(firstname);
xdoc.SelectSingleNode("/students/student[#id='10']/lastname").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/dob").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/class").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/section").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/telephone").InnerXml = TextBox_firstname.Text;
xdoc.Save(filepath);
is there something wrong i dont see...
my xml file looks like this::
<students>
<student>
<id>1</id>
<first_name>ahmad</first_name>
<last_name>hani</last_name>
<DOB>12/5/1998</DOB>
<class>sixth</class>
<section>A</section>
<telephone>06555632</telephone>
</student>
</students>
and i used a query string to load the values from a gridView located in another page using "QueryString"....
thanks in advance.
You can easily do this with Linq to xml:
int id = 9;
XDocument xdoc = XDocument.Load(filepath);
var student = xdoc.Descendants("student")
.Where(s => (int)s.Element("id") == id)
.SingleOrDefault();
if (student != null)
{
student.Element("first_name").Value = TextBox_firstname.Text;
student.Element("last_name").Value = TextBox_lastname.Text;
student.Element("DOB").Value = TextBox_dob.Text;
student.Element("class").Value = TextBox_class.Text;
// etc
}
xdoc.Save(filepath);

How to set attribute to an XML element using linq to xml in C#

i've an xml file like
<Root>
<Steps>
<Step Test="SampleTestOne" Status="Fail" />
<Step Test="SampleTestTwo" Status="Fail" />
</Steps>
</Root>
i need to change or overwrite the attribute value of "Status" in the Step element.
Now i'm using XmlDocument for this
like
XmlDocument XDoc = new XmlDocument();
XDoc.Load(Application.StartupPath + "\\Sample.xml");
XmlNodeList NodeList = XDoc.SelectNodes("//Steps/Step");
foreach (XmlNode Node in NodeList)
{
XmlElement Elem = (XmlElement)Node;
String sTemp = Elem.GetAttribute("Test");
if (sTemp == "SampleTestOne")
Elem.SetAttribute("Status", "Pass");
}
I need search the element and to update the status
is there any way to do this using XDocumentin c#
Thanks in advance
string filename = #"C:\Temp\demo.xml";
XDocument document = XDocument.Load(filename);
var stepOnes = document.Descendants("Step").Where(e => e.Attribute("Test").Value == "SampleTestOne");
foreach (XElement element in stepOnes)
{
if (element.Attribute("Status") != null)
element.Attribute("Status").Value = "Pass";
else
element.Add(new XAttribute("Status", "Pass"));
}
document.Save(filename);
You can use this code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFile);
XmlNode node = xmlDoc.SelectSingleNode("Root/Steps/Step");
node.Attributes["Status"].Value = "True";
xmlDoc.Save(xmlFile);

Categories