Adding XMLElements - c#

I'm trying to add entries to an existing specific xml doc that looks basically alike:
<body>
<setting>
<app name="notepad.exe" folder= "c:\windows\system32\" owner="peter"/>
<app name="calc.exe" folder= "c:\windows\system32\" age="4"/>
</setting>
</body>
The problem I have that I want to add multiple app entries, each width their own attributes, like owner or age etc. (ea not overwritting a single one).
I was thinking of
XDocument doc = new XDocument();
System.xml.XmlElement appnew = new system.Xml.XmlElement("<app name=\"write.exe\" folder="\c:\\windows\\system32\\\"")
Then later add the XmlElement to the sttings section however XMLElement can not be set like that, so I wonder how to add equal node names?

Try following
var doc =
new XDocument(
new XElement("body",
new XElement("setting",
new XElement("app", new XAttribute("age", "4")),
new XElement("app", new XAttribute("owner", "bitchiko"))
)));
In case you have existing XDocument and are trying to add new app element. Then try following
var doc= new XDocument(...);
var settingsXElement = doc.Descendants("setting").Single();
settingsXElement.Add(new XElement("app", new XAttribute("owner", "tchelidze")));

Related

How to generate an XML file dynamically using XDocument?

As I wrote in the subject itself , how can I do that?
Note that solution like this are not appropriate as I want to create child nodes dynamically through running..
new XDocument(
new XElement("root",
new XElement("someNode", "someValue")
)
)
.Save("foo.xml");
I guess this was clear enough the first time but I will write it again:
I need to be able to add child nodes to given parent node while running, in the current syntax I've written this is static generated xml which doesn't contribute me at all because all is known in advance, which is not as my case.
How would you do it with Xdocument, is there away?
If a document has a defined structure and should be filled with dynamic data, you can go like this:
// Setup base structure:
var doc = new XDocument(root);
var root = new XElement("items");
doc.Add(root);
// Retrieve some runtime data:
var data = new[] { 1, 2, 3, 4, 5 };
// Generate the rest of the document based on runtime data:
root.Add(data.Select(x => new XElement("item", x)));
Very simple
Please update your code accordingly
XmlDocument xml = new XmlDocument();
XmlElement root = xml.CreateElement("children");
xml.AppendChild(root);
XmlComment comment = xml.CreateComment("Children below...");
root.AppendChild(comment);
for(int i = 1; i < 10; i++)
{
XmlElement child = xml.CreateElement("child");
child.SetAttribute("age", i.ToString());
root.AppendChild(child);
}
string s = xml.OuterXml;

How to get an independent copy of an XDocument?

I'm trying to create a new XDocument as follows:
var xmlString = _documentDictionary[documentKey].ToString(SaveOptions.DisableFormatting);
XDocument xml = XDocument.Parse(xmlString);
I now have xml which I would have though was a stand-alone instance of a document because I extracted the string from the original document and created a new one from that.
But when I modify xml and then inspect the _documentDictionary[documentKey] I can see that the original document has been modified also.
How can I get a new independent document from the existing collection that I have?
Note:
I've tried these but it doesn't work:
var xmlString = _documentDictionary[documentKey].ToString(SaveOptions.DisableFormatting);
var copyDoc = new XDocument(xmlString);
and
var copyDoc = new XDocument(_documentDictionary[documentKey]);
There is a copy constructor defined for XDocument class:
var newDoc = new XDocument(xml);
You use this constructor to make a deep copy of an XDocument.
This constructor traverses all nodes and attributes in the document
specified in the other parameter, and creates copies of all nodes as
it assembles the newly initialized XDocument.
Quick test
var doc = new XDocument(new XElement("Test"));
var doc2 = new XDocument(doc);
doc.Root.Name = "Test2";
string name = doc.Root.Name.ToString();
string name2 = doc2.Root.Name.ToString();
name is "Test2" and name2 is "Test", what proofs that changes made on doc don't affect doc2.
Try to copy constructor, like;
var newDoc = new XDocument(xml);
From MSDN:
You use this constructor to make a deep copy of an XDocument.
This constructor traverses all nodes and attributes in the document
specified in the other parameter, and creates copies of all nodes as
it assembles the newly initialized XDocument.

save values from textbox to xml document

I want to save my webpage in XML format. I thought of using XmlDocument to save the values. I tried searching it but I couldn't find a proper way for saving the data entered in a textbox to the xml document.
Is there any way? Although incorrect, but this is what I've done till now.
XmlDocument XDoc = new XmlDocument();
// Create root node.
XmlElement XElemRoot = XDoc.CreateElement("Generate_License");
//Add the node to the document.
XDoc.AppendChild(XElemRoot);
XmlElement Xsource = XDoc.CreateElement("General_Info", txtGInfo.ToString());
XElemRoot.AppendChild(Xsource);
You can try with - based on InnerText property
// Create the xml document containe
XmlDocument doc = new XmlDocument();// Create the XML Declaration, and append it to XML document
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec);// Create the root element
XmlElement root = doc.CreateElement("Generate_License");
XmlElement elem= doc.CreateElement("General_Info");
elem.InnerText =txtGInfo.Text;
root.AppendChild(elem);
doc.AppendChild(root);
try this,this is very simple. just that you will need 4.0 .net framework
XDocument doc =
new XDocument(
new XElement("Generate_License",
new XElement("General_Info", txtGInfo.ToString())
)
)
);

how to create N Level xml file

I need to create xml file that have N Level.
for ex. in my below example I have 'AlbumDetails' is root element and 'PrintPackage' is another child root and 'UpgradePackage' is another child root.
Can any one let me know how can i make N Level/Multi Level XML in c#.
<AlbumDetails>
<Album Id="203">
<Institute>Oxford</Institute>
<Venue>Wallingford School</Venue>
<PrintPackage>
<SizeName>Combination Pack</SizeName>
<Price>1.00</Price>
<Weight>60.00</Weight>
<UpgradePackage>
<SizeName>Upgrade 1</SizeName>
<Price>1.00</Price>
<Weight>60.00</Weight>
</UpgradePackage>
<SizeName>Standard Pack</SizeName>
<Price>90.0000</Price>
<Weight>600.0000</Weight>
</PrintPackage>
</Album>
</AlbumDetails>
You are looking for the XmlWriter class.
Update: In case you want to create a document similar to the one above:
var builder = new StringBuilder();
using (var writer = XmlWriter.Create(builder))
{
writer.WriteStartElement("AlbumDetails");
writer.WriteStartElement("Album");
writer.WriteAttributeString("Id", "203");
writer.WriteElementString("Venue", "Wallingford School");
writer.WriteStartElement("PrintPackage");
.... etc.
writer.WriteEndElement(); // close PrintPackage
writer.WriteEndElement(); // close Album
writer.WriteEndElement(); // close AlbumDetails
}
Console.WriteLine(builder.ToString());
Use XDocument and XElement from System.Xml.Linq ( Linq2Xml )
XDocument doc = new XDocument(new XDeclaration("1.0","utf-8","true"),
new XElement("AlbumDetails",
new XElement("Album",new XAttribute("Id","203"),
new XElement("Institute","Oxford"),
new XElement("Venue","Wallingford School")
...
)
)
);
If you are just looking for XElement only, you can build it up in a similar way. You can have a processingElement and create the XElement based on your logic and do
doc.Add(processingElement);
or
ele.Add(processingElement);
They're not really "child roots" - they're just elements which have other child elements.
Personally I'd use LINQ to XML. It's by far the simplest XML API I've used. For example:
var element = new XElement("AlbumDetails",
new XElement("Album",
new XAttribute("ID", 203"),
new XElement("Institute", "Oxford"),
new XElement("Venue", "Wallingford School"),
new XElement("PrintPackage",
new XElement("SizeName", "Combination Pack"),
// etc
new XElement("UpgradePackage",
new XElement("SizeName", "Upgrade 1"),
// etc
)
)
);
Of course, you don't have to build up everything in a single statement - you can add child nodes separately, potentially constructing them entirely separately. Indeed, you may want a separate method to create each "container" element.

Change XML root element name

I have XML stored in string variable:
<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>
Here I want to change XML tag <ItemMasterList> to <Masterlist>. How can I do this?
System.Xml.XmlDocument and the associated classes in that same namespace will prove invaluable to you here.
XmlDocument doc = new XmlDocument();
doc.LoadXml(yourString);
XmlDocument docNew = new XmlDocument();
XmlElement newRoot = docNew.CreateElement("MasterList");
docNew.AppendChild(newRoot);
newRoot.InnerXml = doc.DocumentElement.InnerXml;
String xml = docNew.OuterXml;
I know i am a bit late, but just have to add this answer as no one seems to know about this.
XDocument doc = XDocument.Parse("<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>");
doc.Root.Name = "MasterList";
Which returns the following:
<MasterList>
<ItemMaster>
<fpartno>xxx</fpartno>
<frev>000</frev>
<fac>Default</fac>
</ItemMaster>
</MasterList>
You can use LINQ to XML to parse the XML string, create a new root and add the child elements and attributes of the original root to the new root:
XDocument doc = XDocument.Parse("<ItemMasterList>...</ItemMasterList>");
XDocument result = new XDocument(
new XElement("Masterlist", doc.Root.Attributes(), doc.Root.Nodes()));
Using the XmlDocument way, you can do this as follows (and keep the tree intact):
XmlDocument oldDoc = new XmlDocument();
oldDoc.LoadXml("<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>");
XmlNode node = oldDoc.SelectSingleNode("ItemMasterList");
XmlDocument newDoc = new XmlDocument();
XmlElement ele = newDoc.CreateElement("MasterList");
ele.InnerXml = node.InnerXml;
If you now use ele.OuterXml is will return: (you you just need the string, otherwise use XmlDocument.AppendChild(ele) and you will be able to use the XmlDocument object some more)
<MasterList>
<ItemMaster>
<fpartno>xxx</fpartno>
<frev>000</frev>
<fac>Default</fac>
</ItemMaster>
</MasterList>
As pointed by Will A, we can do it that way but for case where InnerXml equals the OuterXml the following solution will work out:
// Create a new Xml doc object with root node as "NewRootNode" and
// copy the inner content from old doc object using the LastChild.
XmlDocument docNew = new XmlDocument();
XmlElement newRoot = docNew.CreateElement("NewRootNode");
docNew.AppendChild(newRoot);
// The below line solves the InnerXml equals the OuterXml Problem
newRoot.InnerXml = oldDoc.LastChild.InnerXml;
string xmlText = docNew.OuterXml;

Categories

Resources